2013-10-15 75 views
2

我的每個線程都會休眠2000毫秒,並且我有10個這樣的線程,所以我預計總的睡眠時間至少爲20秒,但它的唯一時間是在16-18秒之間。對不起,如果我問一些已經被問到的東西。這是我到目前爲止有:一個線程需要2秒,10個線程需要16-18秒。爲什麼?

import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class MyThreadPoolApp { 
    public static void main(String[] args) { 
     long execTime = System.currentTimeMillis(); 
     CountDownLatch latch = new CountDownLatch(1); 
     ExecutorService executor = Executors.newFixedThreadPool(10); 

     for (int i = 0; i < 10; i++) { 
      executor.submit(new Task()); 
     } 
     System.out.println("threads submitted and waiting execution"); 

     executor.shutdown();   
     try { 
      executor.awaitTermination(1, TimeUnit.MINUTES); 
     } catch (InterruptedException e) { 
     } 
     execTime = System.currentTimeMillis() - execTime; 
     System.out.format("%d threads finished execution \n",Task.getCount()); 
     System.out.println("thread time : " + Task.getTime()); 
     System.out.println("main time : " + execTime); 

    } 
} 

其中任務是:

public class Task implements Runnable { 

    private static long totalTime; 
    private static int count; 
    public static long getTime(){ return totalTime; } 
    public static int getCount(){ return count; } 

    public void run() { 
     count++; 
     long startTime = System.currentTimeMillis(); 
     try { 
      Thread.sleep(2000); 
      totalTime += System.currentTimeMillis() - startTime; 
     } catch (InterruptedException e) {} 
    } 
} 

我的輸出:

threads submitted and waiting execution 
10 threads finished execution 
thread time : 18001 
main time : 2020 
+0

你捉'InterruptedException'並沒有做任何事的。你認爲這有可能出現問題,並中止睡眠? – Michael

+0

好點。我沒有想過。我會嘗試一下。 @Michael Nope,什麼都沒有.. – Somjit

回答

1

因爲您是通過不同的線程TOTALTIME的併發更新搞亂。

試試這個:

import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class MyThreadPoolApp { 
    public static void main(String[] args) { 
     long execTime = System.currentTimeMillis(); 
     CountDownLatch latch = new CountDownLatch(1); 
     ExecutorService executor = Executors.newFixedThreadPool(10); 

     for (int i = 0; i < 10; i++) { 
      executor.submit(new Task()); 
     } 
     System.out.println("threads submitted and waiting execution"); 

     executor.shutdown(); 
     try { 
      executor.awaitTermination(1, TimeUnit.MINUTES); 
     } catch (InterruptedException e) { 
     } 
     execTime = System.currentTimeMillis() - execTime; 
     System.out.format("%d threads finished execution \n",Task.getCount()); 
     System.out.println("thread time : " + Task.getTime()); 
     System.out.println("main time : " + execTime); 
    } 
} 

class Task implements Runnable { 

    private static long totalTime; 
    private static int count; 
    public static long getTime(){ 
     synchronized(Task.class){ 
      return totalTime; 
     } 
    } 
    private static void addTime(long time){ 
     synchronized(Task.class){ 
      totalTime = totalTime + time; 
     } 
    } 
    public static int getCount(){ return count; } 

    public void run() { 
     count++; 
     long startTime = System.currentTimeMillis(); 
     try { 
      Thread.sleep(2000); 
      addTime(System.currentTimeMillis() - startTime); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

編輯 如你所願,同步內run()方法:

import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class MyThreadPoolApp { 
    public static void main(String[] args) { 
     long execTime = System.currentTimeMillis(); 
     CountDownLatch latch = new CountDownLatch(1); 
     ExecutorService executor = Executors.newFixedThreadPool(10); 

     for (int i = 0; i < 10; i++) { 
      executor.submit(new Task()); 
     } 
     System.out.println("threads submitted and waiting execution"); 

     executor.shutdown(); 
     try { 
      executor.awaitTermination(1, TimeUnit.MINUTES); 
     } catch (InterruptedException e) { 
     } 
     execTime = System.currentTimeMillis() - execTime; 
     System.out.format("%d threads finished execution \n",Task.getCount()); 
     System.out.println("thread time : " + Task.getTime()); 
     System.out.println("main time : " + execTime); 
    } 
} 

class Task implements Runnable { 

    private static long totalTime; 
    private static int count; 
    public static long getTime(){ 
     synchronized(Task.class){ 
      return totalTime; 
     } 
    } 
    public static int getCount(){ return count; } 

    public void run() { 
     count++; 
     long startTime = System.currentTimeMillis(); 
     try { 
      Thread.sleep(2000); 
      synchronized(Task.class){ 
       totalTime += System.currentTimeMillis() - startTime; 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

如果synchronized被放置在run()方法中,該怎麼辦?將保存兩個額外的同步方法不會呢? – Somjit

+0

是的,你可以把同步塊內run()方法來更新總時間!但是隻能在Task.class上同步,因爲你正在更新類變量。 – UDPLover

相關問題