multi thread for Java

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.

 1 package leetcode;
 2 
 3 import java.util.Hashtable;
 4 import java.util.Iterator;
 5 import java.util.Map.Entry;
 6 
 7 public class MultiThread {
 8     static Hashtable<Integer, Integer> sharedTable = new Hashtable<Integer, Integer>();
 9     static final class ThreadOne implements Runnable{
10         public ThreadOne(){
11             
12         }
13         @Override
14         public void run() {
15             // TODO Auto-generated method stub
16             System.out.println("Thread One running: add key-value pair to sharedTable");
17             for(int i = 0; i < 20; i ++){
18                 sharedTable.put(i, i);
19                 System.out.println("Put " + i + " into sharedTable");
20             }
21         }
22     }
23     
24     static final class ThreadTwo implements Runnable{
25         public ThreadTwo(){
26             
27         }
28         @Override
29         public void run(){
30             System.out.println("Thread Two running: iterate the hashtable");
31             Iterator it = sharedTable.entrySet().iterator();
32             while(it.hasNext()){
33                 Entry<Integer, Integer> entry = (Entry<Integer, Integer>) it.next();
34                 System.out.println("entry in sharedTable:" + entry.getKey() +"  with value:" + entry.getValue());
35             }
36         }
37     }
38     
39     public static void main(String[] agrs){
40         ThreadOne t1 = new ThreadOne();
41         ThreadTwo t2 = new ThreadTwo();
42         System.out.println("Thread start...");
43         new Thread(t1).start();
44         new Thread(t2).start();
45         System.out.println("Thread all started.");
46     }
47 }

I make two thread.

ThreadOne do put to hashTable.

ThreadTwo use an iterator to traversal the hashTable.

 

However, the output is:

 1 Thread start...
 2 Thread all started.
 3 Thread Two running: iterate the hashtable
 4 Thread One running: add key-value pair to sharedTable
 5 Put 0 into sharedTable
 6 Put 1 into sharedTable
 7 Put 2 into sharedTable
 8 Put 3 into sharedTable
 9 Put 4 into sharedTable
10 Put 5 into sharedTable
11 Put 6 into sharedTable
12 Put 7 into sharedTable
13 Put 8 into sharedTable
14 Put 9 into sharedTable
15 Put 10 into sharedTable
16 Put 11 into sharedTable
17 Put 12 into sharedTable
18 Put 13 into sharedTable
19 Put 14 into sharedTable
20 Put 15 into sharedTable
21 Put 16 into sharedTable
22 Put 17 into sharedTable
23 Put 18 into sharedTable
24 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?

 1 package leetcode;
 2 
 3 import java.util.Hashtable;
 4 import java.util.Iterator;
 5 import java.util.Map.Entry;
 6 
 7 public class MultiThread {
 8     static final class Shared{
 9         private static Hashtable<Integer, Integer> sharedTable = new Hashtable<Integer, Integer>();
10         
11         public Shared(){
12             sharedTable = new Hashtable<Integer, Integer>();
13         }
14         public synchronized static void put(Integer key, Integer val){
15             System.out.println("put (" + key + ":" + val + ")into sharedTable.");
16             sharedTable.put(key, val);
17         }
18         
19         public synchronized static Integer get(Integer key){
20             return sharedTable.get(key);
21         }
22         
23         public synchronized static Boolean containsKey(Integer key){
24             return sharedTable.containsKey(key);
25         }
26         
27         public synchronized static void traversal(){
28             System.out.println("traversal on the sharedTable...");
29             Iterator it = sharedTable.values().iterator();
30             while(it.hasNext()){
31                 Integer val = (Integer)it.next();
32                 System.out.println("sharedTable contains val: " + val);
33             }
34             System.out.println("Finish traversal.");
35         }
36 
37     }
38         static final class ThreadOne implements Runnable{
39         public ThreadOne(){
40             
41         }
42         @Override
43         public void run() {
44             // TODO Auto-generated method stub
45             System.out.println("Thread One running: add key-value pair to sharedTable");
46             for(int i = 0; i < 20; i ++){
47                 Shared.put(i, i);
48             }
49         }
50     }
51     
52     static final class ThreadTwo implements Runnable{
53         public ThreadTwo(){
54             
55         }
56         @Override
57         public void run(){
58             System.out.println("Thread Two running: iterate the hashtable");
59             Shared.traversal();
60         }
61     }
62     
63     public static void main(String[] agrs) throws InterruptedException{
64         ThreadOne t1 = new ThreadOne();
65         ThreadTwo t2 = new ThreadTwo();
66         System.out.println("Thread start...");
67         new Thread(t1).start();
68         Thread.sleep(1);
69         new Thread(t2).start();
70         System.out.println("Thread all started.");
71     }
72 }

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:

 1 Thread start...
 2 Thread One running: add key-value pair to sharedTable
 3 put (0:0)into sharedTable.
 4 put (1:1)into sharedTable.
 5 put (2:2)into sharedTable.
 6 put (3:3)into sharedTable.
 7 Thread all started.
 8 put (4:4)into sharedTable.
 9 put (5:5)into sharedTable.
10 put (6:6)into sharedTable.
11 Thread Two running: iterate the hashtable
12 put (7:7)into sharedTable.
13 traversal on the sharedTable...
14 sharedTable contains val: 7
15 sharedTable contains val: 6
16 sharedTable contains val: 5
17 sharedTable contains val: 4
18 sharedTable contains val: 3
19 sharedTable contains val: 2
20 sharedTable contains val: 1
21 sharedTable contains val: 0
22 Finish traversal.
23 put (8:8)into sharedTable.
24 put (9:9)into sharedTable.
25 put (10:10)into sharedTable.
26 put (11:11)into sharedTable.
27 put (12:12)into sharedTable.
28 put (13:13)into sharedTable.
29 put (14:14)into sharedTable.
30 put (15:15)into sharedTable.
31 put (16:16)into sharedTable.
32 put (17:17)into sharedTable.
33 put (18:18)into sharedTable.
34 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:

 1 package leetcode;
 2 
 3 import java.util.Hashtable;
 4 import java.util.Iterator;
 5 
 6 public class MultiThread {
 7         static final class ThreadOne implements Runnable{
 8         public ThreadOne(){
 9             
10         }
11         @Override
12         public void run() {
13             // TODO Auto-generated method stub
14             System.out.println("Thread One running: add key-value pair to sharedTable");
15             for(int i = 0; i < 100; i ++){
16                 synchronized(sharedTable){
17                     System.out.println("put (" + i + ":" + i + ")into sharedTable.");
18                     sharedTable.put(i, i);
19                 }
20             }
21         }
22     }
23     
24     static final class ThreadTwo implements Runnable{
25         public ThreadTwo(){
26             
27         }
28         @Override
29         public void run(){
30             System.out.println("Thread Two running: iterate the hashtable");
31             System.out.println("traversal on the sharedTable...");
32             synchronized(sharedTable){
33                 Iterator it = sharedTable.values().iterator();
34                 while(it.hasNext()){
35                     Integer val = (Integer)it.next();
36                     System.out.println("sharedTable contains val: " + val);
37                 }
38             }
39             System.out.println("Finish traversal.");
40         }
41     }
42     
43     public static void main(String[] agrs) throws InterruptedException{
44         ThreadOne t1 = new ThreadOne();
45         ThreadTwo t2 = new ThreadTwo();
46         System.out.println("Thread start...");
47         new Thread(t1).start();
48         Thread.sleep(1);
49         new Thread(t2).start();
50         System.out.println("Thread all started.");
51     }
52     private static Hashtable<Integer, Integer> sharedTable = new Hashtable<Integer, Integer>();
53 }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。