2017-05-11 11 views
6

私はそれを期待するとして、次のコードは動作しません。Javaの同期スレッドが期待通りに動作していない

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

class Worker implements Runnable { 

    public void run() { 
     System.out.println("Started."); 
     process(); 

    } 
    private Random random = new Random(); 

    private Object lock1 = new Object(); 
    private Object lock2 = new Object(); 

    private static List<Integer> list1 = new ArrayList<Integer>(); 
    private static List<Integer> list2 = new ArrayList<Integer>(); 

    public void stageOne() { 

     synchronized (lock1) { 

      try { 
       Thread.sleep(1); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      list1.add(random.nextInt(100)); 
     } 

    } 

    public void stageTwo() { 

     synchronized (lock2) { 
      try { 
       Thread.sleep(1); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      list2.add(random.nextInt(100)); 
     } 
    } 

    public void process() { 
     for(int i=0; i<1000; i++) { 
      stageOne(); 
      stageTwo(); 
     } 
    } 
    public static void show() { 
     System.out.println("List1: " + list1.size()); 
     System.out.println("List2: " + list2.size()); 
    } 
} 

public class JavaTest { 

    public static void main(String[] args) { 

     long start = System.currentTimeMillis(); 

     Thread t1 = new Thread(new Worker()); 
     t1.start(); 
     Thread t2 = new Thread(new Worker()); 
     t2.start(); 

     try { 
      t1.join(); 
      t2.join(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     System.out.println("Completed."); 

     long end = System.currentTimeMillis(); 

     System.out.println("Time taken: " + (end - start)); 

     Worker.show(); 
    } 

} 

私はこのプログラムを実行すると、私はlist1list2 2000の項目それぞれにプログラムのために含まれていることを期待約2000ミリ秒かかる。しかし、2000ミリ秒ほどで完了していますが、多くの場合、2000件未満のリストを取得します。時々私も、私はstageOnestageTwoの各ロックが互いに干渉のスレッドを停止する必要があることを期待しArrayOutOfBounds例外

Started. 
Started. 
Exception in thread "Thread-1" java.lang.ArrayIndexOutOfBoundsException: 163 
    at java.util.ArrayList.add(ArrayList.java:459) 
    at Worker.stageOne(JavaTest.java:34) 
    at Worker.process(JavaTest.java:53) 
    at Worker.run(JavaTest.java:14) 
    at java.lang.Thread.run(Thread.java:748) 
Completed. 
Time taken: 2217 
List1: 1081 
List2: 1079 

を取得します。しかし、それはそうではないようです。このコードの問題は何ですか?

答えて

8

ロックオブジェクトは静的ではないため、各スレッドは別のモニタで同期しています。したがって、ロックはまったく効果がありません。

関連する問題