2012-07-09 58 views
0

我不確定這樣的代碼是否安全。我需要從DB中讀取一個名稱,並且我需要使用10個線程,每個名稱都帶一個名稱,然後在run內部調用一個需要此名稱作爲參數的函數。在循環中創建線程的正確性

是10個線程適合運行英特爾酷睿i7 8GB內存的電腦?我如何知道我可以創建的可接受的線程數?這段代碼是正確和安全的嗎?

我在Dietel的書中發現,他們在Executor之前創建了新的線程。他們添加一行:PrintTask task1 = new PrintTask("thread1");

檢查:http://www.deitel.com/articles/java_tutorials/20051126/JavaMultithreading_Tutorial_Part4.html),但發現在下面的方法(沒有新的說法):http://www.vogella.com/articles/JavaConcurrency/article.html

換句話說,我應該在循環之前創建它們?兩個引用使用不同的方法,我很困惑。其代碼是正確的做法是:

 ExecutorService Executor = Executors.newFixedThreadPool(10); 

     while(resultSet.next()) 
      { 
       name=resultSet.getString("hname"); 
       MyRunnable worker = new MyRunnable(name); 

       Executor.execute(worker); 
       Counter++; 
     } 


    Executor.shutdown(); 
    System.out.println("thread shutdown"); 

// Wait until all threads are finish 
while (! Executor.isTerminated()) { 

} 
System.out.println("Finished all threads"); 

OR

MyRunnable task1 = new MyRunnable(name); 
MyRunnable task2 = new MyRunnable(name); 
MyRunnable task3 = new MyRunnable(name); 
MyRunnable task4 = new MyRunnable(name); 
MyRunnable task5 = new MyRunnable(name); 
MyRunnable task6 = new MyRunnable(name); 
MyRunnable task7 = new MyRunnable(name); 
MyRunnable task8 = new MyRunnable(name); 
MyRunnable task9 = new MyRunnable(name); 
MyRunnable task10 = new MyRunnable(name); 


     ExecutorService Executor = Executors.newFixedThreadPool(10); 

     while(resultSet.next()) 
      { 
       name=resultSet.getString("hname"); 
       MyRunnable worker = new MyRunnable(name); 

       Executor.execute(worker); 
       Counter++; 
     } 


    Executor.shutdown(); 
    System.out.println("thread shutdown"); 

// Wait until all threads are finish 
while (! Executor.isTerminated()) { 

} 
System.out.println("Finished all threads"); 

而且,在實現運行MyRunnable類的構造函數,我一定要明確地啓動線程或是否Executor.execute(worker)足夠在這種情況下, 。

+2

的可運行是*不*線程。他們只是有一個運行方法,告訴線程將最終執行它該做什麼。是的,Executor負責啓動和停止線程。 – Thilo 2012-07-09 04:42:17

+0

'MyRunnable.shutdown()'做了什麼?你的意思是'Executor.shutdown()'? – Thilo 2012-07-09 04:43:10

+0

@Thilo:是的,它應該是'Executor.shutdown'。現在更正。 – 2012-07-09 04:52:01

回答

3

我會像改寫它:

ExecutorService executor = Executors.newFixedThreadPool(10); 

while(resultSet.next()) 
{ 
    name=resultSet.getString("hname"); 
    MyRunnable worker = new MyRunnable(name); 
    executor.submit(worker); 
    counter++; 
} 


executor.shutdown(); 
System.out.println("thread shutdown"); 

executor.awaitTermination(60, TimeUnit.SECONDS); 
System.out.println("Finished all threads"); 

變量在較低的情況下,而不是awaitTermination的循環。

要使用的線程數量取決於幾個因素:機器,任務的數量來執行的任務的「大小」等

+0

我怎樣才能決定等待時間。 60秒可能足以確保所有子線程在我結束主線程之前完成?這就是爲什麼我使用空循環,我不能決定時間?我對嗎 ? – 2012-07-09 05:08:27

+0

這是否意味着無需編寫創建新的線程語句?也不需要在構造函數中明確地啓動它? – 2012-07-09 05:09:45

+0

等待時間由您決定。時間應該代表你可以說「在這個時候,如果它沒有完成,這意味着有什麼問題......」的時間。它可以是100ms,也可以是1天......您不需要創建線程並啓動線程,執行程序就是爲了這樣做而設計的,並且以高效的方式執行。 – tibo 2012-07-09 06:49:50

0

如果這是您的擔心,那麼您的第一個循環沒有任何線程不安全。我唯一關心的是你用什麼Counter變量:你知道你不能依賴它的價值在你的MyRunnable之內,對吧?

+0

我沒有使用myrunnable裏面的計數器。我發送它作爲線程創建的計數器,但我發現這個計數器並不代表線程的數量,因爲我有一個固定的池。我的構造函數是:'MyRunnable(String xname){this.name = xname;}'。沒有任何東西可以告訴我的線程啓動?不確定。 – 2012-07-09 07:25:27