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 }

 

你可能感兴趣的:(thread)