2012-07-04 78 views
1

我有一個簡單的程序。主要思想是,我有一個存儲在MySQL數據庫中的名稱列表,我想同時對這些名稱執行一些操作,但是當然,每個線程都應該使用不同的名稱。下一個線程應該處理上一個線程採用的下一個名稱。我創建了線程池,我在循環內部創建了新線程,然後執行可運行子程序,以便對該名稱執行操作。在此示例中,操作是打印從DB中選擇的名稱。該程序正在跳過數據庫中的一些名稱,並重復了6次姓。我的程序有什麼問題?我還是新來的線索,請原諒我的錯誤。Java和數據庫中的多線程

這是主要的功能:

import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Main { 

    public static volatile ResultSet resultSet = null; 
    private static Statement statement = null; 

    public static void main(String[] args) throws SQLException 

    { 
     DBConnection.ConnectDB(); //connect to database 


      statement = DBConnection.con.createStatement(); 
      resultSet = statement.executeQuery("select Name from schema.table1"); //select statement 

      String name = null; 


      // create ExecutorService to manage threads 
      ExecutorService threadExecutor = Executors.newFixedThreadPool(3); 

      // create and name each runnable 
      while(resultSet.next()) 
      { 
       name=resultSet.getString("Name"); 
       MyRunnable task1 = new MyRunnable(name); 
       threadExecutor.execute(task1); 
      } 


     // This will make the executor accept no new threads 
     // and finish all existing threads in the queue 

      threadExecutor.shutdown(); 
     // Wait until all threads are finish 
     while (! threadExecutor.isTerminated()) { 

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

而且MyRunnable類:

import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 

import com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException; 

public class MyRunnable implements Runnable{ 
private static String nn; 


MyRunnable (String ss) { synchronized (this) { 
    this.nn=ss; 
} 
} 


public void run() 
{ 

    System.out.println("hello "+ nn); 
} 
} 

回答

6

這肯定是一個問題。去除靜電。

private static String nn; 

成爲

private String nn; 
+0

看起來這一定是問題...... @JuryA,你應該接受這個! –

+0

@ tjg184:修復private static String nn後;我從數據庫中檢索到名稱後顯示的名稱沒有重複,但沒有以正確的順序存儲在數據庫中。我按照這個順序得到它們:1 - 2 - 3 - 4 - 5 - 7 - 6 - 9 - 8 - 11 - 10 - 13 - 12 - 15 - 14 - 17 - 16 - 19 - 18 - 20 (從1到20)這是正常情況下應該發生的線程還是有什麼問題? –

+0

另一件事,我有的問題是,我必須閱讀一長串名稱,並處理每一個名單,這需要時間,我用線程來使這個速度更快。我上面使用的方法是否正確(從數據庫中檢索名稱並使用構造函數將其分配給每個線程)?或者是否有可能讓每個線程在循環中自己讀取名稱,以便每個線程都有自己的循環來讀取名稱?但是每個線程都應該檢索最後一個線程檢索到的名稱。 –

0

作爲一個側面說明,此塊:

while (! threadExecutor.isTerminated()) { 
} 

應改爲:

while (! threadExecutor.isTerminated()) { 
    try { 
     threadExecutor.awaitTermination(1, TimeUnit.SECOND); 
    } 
    catch (InterruptedException e) { 
     // you have to determine if someone can interrupt your wait 
     // for the full termination of the executor, but most likely, 
     // you'll do nothing here and swallow the exception, or rethrow 
     // it in a RuntimeException 
    } 
} 

你不應該做一個忙等待像你」重新做。您將使用不必要的CPU週期,並將處理時間從池中的實際線程中移走。

+0

好的。但是你的代碼似乎等待時間是1秒。只要 ??你如何授予所有線程在1秒內退出。在退出主線程之前? –

+0

這就是爲什麼有一個while循環。你可以隨時將等待時間設置爲一天或某些事情,如果你願意,可以避開while循環。 – Matt

+0

我曾經在Future對象列表上調用get()方法來理解線程是否已經終止。你認爲你的解決方案更好嗎?謝謝 – nuvio