I try to do a testing for HashTable Sychronized behavior today.

As an Sychronized Object, HashTable already an Sychronized at put and get function. I wanna to know more about the iterator behaviors on multi-threading.

 package leetcode;

 import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry; public class MultiThread {
static Hashtable<Integer, Integer> sharedTable = new Hashtable<Integer, Integer>();
static final class ThreadOne implements Runnable{
public ThreadOne(){ }
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread One running: add key-value pair to sharedTable");
for(int i = 0; i < 20; i ++){
sharedTable.put(i, i);
System.out.println("Put " + i + " into sharedTable");
}
}
} static final class ThreadTwo implements Runnable{
public ThreadTwo(){ }
@Override
public void run(){
System.out.println("Thread Two running: iterate the hashtable");
Iterator it = sharedTable.entrySet().iterator();
while(it.hasNext()){
Entry<Integer, Integer> entry = (Entry<Integer, Integer>) it.next();
System.out.println("entry in sharedTable:" + entry.getKey() +" with value:" + entry.getValue());
}
}
} public static void main(String[] agrs){
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
System.out.println("Thread start...");
new Thread(t1).start();
new Thread(t2).start();
System.out.println("Thread all started.");
}
}

I make two thread.

ThreadOne do put to hashTable.

ThreadTwo use an iterator to traversal the hashTable.

However, the output is:

 Thread start...
Thread all started.
Thread Two running: iterate the hashtable
Thread One running: add key-value pair to sharedTable
Put 0 into sharedTable
Put 1 into sharedTable
Put 2 into sharedTable
Put 3 into sharedTable
Put 4 into sharedTable
Put 5 into sharedTable
Put 6 into sharedTable
Put 7 into sharedTable
Put 8 into sharedTable
Put 9 into sharedTable
Put 10 into sharedTable
Put 11 into sharedTable
Put 12 into sharedTable
Put 13 into sharedTable
Put 14 into sharedTable
Put 15 into sharedTable
Put 16 into sharedTable
Put 17 into sharedTable
Put 18 into sharedTable
Put 19 into sharedTable

Iterator is initated, however it.hasNext() return false and then exit.

This means that Iterator is broken by put function. It is not sychronized for thread.

So how to make it sychronized?

 package leetcode;

 import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry; public class MultiThread {
static final class Shared{
private static Hashtable<Integer, Integer> sharedTable = new Hashtable<Integer, Integer>(); public Shared(){
sharedTable = new Hashtable<Integer, Integer>();
}
public synchronized static void put(Integer key, Integer val){
System.out.println("put (" + key + ":" + val + ")into sharedTable.");
sharedTable.put(key, val);
} public synchronized static Integer get(Integer key){
return sharedTable.get(key);
} public synchronized static Boolean containsKey(Integer key){
return sharedTable.containsKey(key);
} public synchronized static void traversal(){
System.out.println("traversal on the sharedTable...");
Iterator it = sharedTable.values().iterator();
while(it.hasNext()){
Integer val = (Integer)it.next();
System.out.println("sharedTable contains val: " + val);
}
System.out.println("Finish traversal.");
} }
static final class ThreadOne implements Runnable{
public ThreadOne(){ }
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread One running: add key-value pair to sharedTable");
for(int i = 0; i < 20; i ++){
Shared.put(i, i);
}
}
} static final class ThreadTwo implements Runnable{
public ThreadTwo(){ }
@Override
public void run(){
System.out.println("Thread Two running: iterate the hashtable");
Shared.traversal();
}
} public static void main(String[] agrs) throws InterruptedException{
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
System.out.println("Thread start...");
new Thread(t1).start();
Thread.sleep(1);
new Thread(t2).start();
System.out.println("Thread all started.");
}
}

One way to solve is put sharedResources into an Bean. And for all getter / setter / traversal make them sychronized. All the customer/ producor have to call this class to use resources( this is the idea of broker, who is working between clinet and servers).

output:

 Thread start...
Thread One running: add key-value pair to sharedTable
put (0:0)into sharedTable.
put (1:1)into sharedTable.
put (2:2)into sharedTable.
put (3:3)into sharedTable.
Thread all started.
put (4:4)into sharedTable.
put (5:5)into sharedTable.
put (6:6)into sharedTable.
Thread Two running: iterate the hashtable
put (7:7)into sharedTable.
traversal on the sharedTable...
sharedTable contains val: 7
sharedTable contains val: 6
sharedTable contains val: 5
sharedTable contains val: 4
sharedTable contains val: 3
sharedTable contains val: 2
sharedTable contains val: 1
sharedTable contains val: 0
Finish traversal.
put (8:8)into sharedTable.
put (9:9)into sharedTable.
put (10:10)into sharedTable.
put (11:11)into sharedTable.
put (12:12)into sharedTable.
put (13:13)into sharedTable.
put (14:14)into sharedTable.
put (15:15)into sharedTable.
put (16:16)into sharedTable.
put (17:17)into sharedTable.
put (18:18)into sharedTable.
put (19:19)into sharedTable.

Or dont sychronized the whole function, only for the part that use the resource. In this way, actually we dont need an specific class to encapture the resources:

 package leetcode;

 import java.util.Hashtable;
import java.util.Iterator; public class MultiThread {
static final class ThreadOne implements Runnable{
public ThreadOne(){ }
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread One running: add key-value pair to sharedTable");
for(int i = 0; i < 100; i ++){
synchronized(sharedTable){
System.out.println("put (" + i + ":" + i + ")into sharedTable.");
sharedTable.put(i, i);
}
}
}
} static final class ThreadTwo implements Runnable{
public ThreadTwo(){ }
@Override
public void run(){
System.out.println("Thread Two running: iterate the hashtable");
System.out.println("traversal on the sharedTable...");
synchronized(sharedTable){
Iterator it = sharedTable.values().iterator();
while(it.hasNext()){
Integer val = (Integer)it.next();
System.out.println("sharedTable contains val: " + val);
}
}
System.out.println("Finish traversal.");
}
} public static void main(String[] agrs) throws InterruptedException{
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
System.out.println("Thread start...");
new Thread(t1).start();
Thread.sleep(1);
new Thread(t2).start();
System.out.println("Thread all started.");
}
private static Hashtable<Integer, Integer> sharedTable = new Hashtable<Integer, Integer>();
}

multi thread for Java的更多相关文章

  1. Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

    学习架构探险,从零开始写Java Web框架时,在学习到springAOP时遇到一个异常: "C:\Program Files\Java\jdk1.7.0_40\bin\java" ...

  2. Exception in thread "main" java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

    在学习CGlib动态代理时,遇到如下错误: Exception in thread "main" java.lang.NoSuchMethodError: org.objectwe ...

  3. GUI学习中错误Exception in thread "main" java.lang.NullPointerException

    运行时出现错误:Exception in thread "main" java.lang.NullPointerException 该问题多半是由于用到的某个对象只进行了声明,而没 ...

  4. 执行打的maven jar包时出现“Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes”

    Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for ...

  5. Exception in thread "main" java.lang.ExceptionInInitializerError

    Exception in thread "main" java.lang.ExceptionInInitializerErrorCaused by: java.util.Missi ...

  6. 编译运行java程序出现Exception in thread "main" java.lang.UnsupportedClassVersionError: M : Unsupported major.minor version 51.0

    用javac编译了一个M.java文件, 然后用java M执行,可是出现了下面这个错误. Exception in thread "main" java.lang.Unsuppo ...

  7. dom4j使用xpath报异常 Exception in thread "main" java.lang.NoClassDefFoundError: org/jaxen/NamespaceContext

    Exception in thread "main" java.lang.NoClassDefFoundError: org/jaxen/NamespaceContext      ...

  8. Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1

    场景:eclipse中编写java中用到数组 问题: 程序不报错但是运行过程中 终止,显示字样 “ Exception in thread "main" java.lang.Arr ...

  9. dbca:Exception in thread "main" java.lang.UnsatisfiedLinkError: get

    在64位的操作系统安装oracle10g 软件安装完成后,使用dbca建库的时候报下面的错: $ dbcaUnsatisfiedLinkError exception loading native l ...

随机推荐

  1. 1797: [Ahoi2009]Mincut 最小割

    1797: [Ahoi2009]Mincut 最小割 链接 分析: 题意为:问一条边是否可能存在于最小割中,是否一定存在于最小割中. 首先最小割的边一定是满流的边.且这条边点两个端点u.v中,至少一个 ...

  2. 【Java源码解析】Thread

    简介 线程本质上也是进程.线程机制提供了在同一程序内共享内存地址空间运行的一组线程.对于内核来讲,它就是进程,只是该进程和其他一下进程共享某些资源,比如地址空间.在Java语言里,Thread类封装了 ...

  3. jenkins maven设置settings.xml

    环境:jenkins.2.89.3 1.安装settings.xml管理插件Config File Provider Plugin  系统管理->管理插件->搜索Config File P ...

  4. gh-ost的延迟控制机制

    root@sbtest04:46:19>select * from _yougege_ghc limit 10\G*************************** 1. row ***** ...

  5. 第一道防线__SpringMVC配置拦截器

    这几天在公司自己开发一个小系统,但是系统的安全性也得考虑,起初没注意,赶急就光关心业务逻辑和实现效果.最后老大一出手,就把最严重的问题指出来了,他说你这根本没安全性可言,于是我试着将公司使用的spri ...

  6. JavaScript——变量与基本数据类型

    前言 JavaScript中的变量为松散类型,所谓松散类型就是指当一个变量被申明出来就可以保存任意类型的值,就是不像SQL一样申明某个键值为int就只能保存整型数值,申明varchar只能保存字符串. ...

  7. 把模块有关联的放在一个文件夹中 在python2中调用文件夹名会直接失败 在python3中调用会成功,但是调用不能成功的解决方案

    把模块有关联的放在一个文件夹中 在python2中调用文件夹名会直接失败在python3中调用会成功,但是调用不能成功 解决办法是: 在该文件夹下加入空文件__init__.py python2会把该 ...

  8. 007 --MySQL索引底层实现原理

    MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的最主要功能之一.我们都希望查 ...

  9. CHAPTER 25 The Greatest Show on Earth 第25章 地球上最壮观的演出

    CHAPTER 25 The Greatest Show on Earth 第25章 地球上最壮观的演出 Go for a walk in the countryside and you will f ...

  10. Redis的C语言客户端(hiredis)的安装和使用

    关键词:hiredis, cRedis, redis clients, redis客户端, C客户端, 华为云分布式缓存服务 hiredis是一个非常全面的C语言版redis接口库,支持所有命令.管道 ...