• 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 }
  • 相关阅读:
    oracle笔记
    随笔
    EclipsePDT PHP的开发环境配置
    winXP的系统如何避免他人在不需要密码的情况进入安全模式
    WINDOWS图片和传真查看器找不到
    Oracle常用语句大全
    jdbc连接oracle
    jdk与jre的区别
    mysql手工注入.md
    sql手工注入.md
  • 原文地址:https://www.cnblogs.com/reynold-lei/p/4356671.html
Copyright © 2020-2023  润新知