2015-08-09 168 views
1

我研究java concurency。爲什麼我的多線程代碼導致掛起?

我想估計時間執行依賴於線程數(讀寫)

我的代碼:

public class Task5 { 
    public static int [] readerThreadCount = {1,10,100,1000}; 
    public static int [] writerThreadCount = {10, 1000, 1000000}; 


    public static void main(String[] args) throws InterruptedException { 
     for (int readCount : readerThreadCount) { 
      for (int writeCount : writerThreadCount) { 
       System.out.println(readCount + "/" + writeCount + " = " + test(readCount, writeCount, new ArrayHolderBySynchronized())); 
      } 
     } 

    } 

    private static long test(int readCount, int writeCount, ArrayHolder arrayHolder) throws InterruptedException { 
     CountDownLatch countDownLatch = new CountDownLatch(readCount + writeCount); 
     List<Thread> threads = new ArrayList<>(); 
     for (int i = 0; i < readCount; i++) { 
      threads.add(new Thread(new ArrayReader(arrayHolder, countDownLatch))); 
     } 
     for (int i = 0; i < writeCount; i++) { 
      threads.add(new Thread(new ArrayWriter(arrayHolder, countDownLatch))); 

     } 
     for(Thread thread:threads){ 
      thread.start(); 
     } 
     countDownLatch.await();//all threads started 
     long start = System.currentTimeMillis(); 
     for (Thread thread : threads) { 
      thread.join(); 
     } 
     return System.currentTimeMillis() - start; 

    } 
} 

class ArrayHolderBySynchronized extends ArrayHolder { 

    @Override 
    public synchronized int get(int index) { 
     return arr[index]; 
    } 

    @Override 
    public synchronized void write(int index, int value) { 
     arr[index] = value; 
    } 
} 

class ArrayReader implements Runnable { 
    ArrayHolder arrayHolder; 
    CountDownLatch countDownLatch; 

    ArrayReader(ArrayHolder arrayHolder, CountDownLatch countDownLatch) { 
     this.arrayHolder = arrayHolder; 
     this.countDownLatch = countDownLatch; 
    } 

    @Override 
    public void run() { 
     countDownLatch.countDown(); 
     arrayHolder.get(new Random().nextInt(ArrayHolder.ARRAY_SIZE)); 
    } 
} 

class ArrayWriter implements Runnable { 
    ArrayHolder arrayHolder; 
    CountDownLatch countDownLatch; 

    ArrayWriter(ArrayHolder arrayHolder, CountDownLatch countDownLatch) { 
     this.arrayHolder = arrayHolder; 
     this.countDownLatch = countDownLatch; 
    } 

    @Override 
    public void run() { 
     countDownLatch.countDown(); 
     arrayHolder.write(new Random().nextInt(ArrayHolder.ARRAY_SIZE), -1); 
    } 
} 

abstract class ArrayHolder { 
    public static int ARRAY_SIZE = 1_000_000; 
    protected int[] arr = generateArray(); 

    private int[] generateArray() { 
     int[] arr = new int[ARRAY_SIZE]; 
     for (int i = 0; i < ARRAY_SIZE; i++) { 
      arr[i] = i + 1; 
     } 
     return arr; 
    } 

    public abstract int get(int index); 

    public abstract void write(int index, int value); 
} 

它輸出

1/10 = 0 
1/1000 = 1 

和掛起。

我不知道爲什麼。

請大家幫忙。

+2

你有沒有像這樣的1000000個核心。 – 2015-08-09 14:07:15

+0

太大數字? – gstackoverflow

+2

是的。產生1000000個線程是無稽之談。您通常會選擇一些等同於處理器併發能力的線程,您可以考慮使用這些併發能力,然後平衡它們之間的工作負載。對於四核 - > 4線程。 – 2015-08-09 14:12:44

回答

1

它不掛,啓動百萬線程只是時間比首發1000線(一兩分鐘,我的機器上)長1000次:

> java Task5 

1/10 = 0 
1/1000 = 1 
1/1000000 = 63 
10/10 = 0 
10/1000 = 0 
10/1000000 = 60 
100/10 = 0 
100/1000 = 0 
100/1000000 = 63 
1000/10 = 0 
1000/1000 = 0 
1000/1000000 = 60 

你的下一個問題可能是爲什麼你的測試報告一需要花費數分鐘才能執行的時間爲60毫秒。這是因爲開始一個線程比倒計時鎖存器,讀取或寫入單個數組元素要昂貴得多,而且只能測量後者。

相關問題