2016-11-22 62 views
-1

我有一個需求來更新數據庫中可用的300 000條記錄。當我編寫獨立程序時,它花費了25-30分鐘來更新5 000條記錄。所以要完成所有的記錄可能需要30個小時。然後我想我會寫一個多線程程序。我創建了2個線程,然後開始更新,同時花費30分鐘處理5k個記錄。何處使用多線程概念

就我所知,我們使用線程來併發訪問一個方法,並且在這種情況下它不會加速更新。

對於上述情況,我必須做些什麼來減少時間。多線程的實際用途是什麼

class MyThread1 extends Thread{ 
    public static String getTaskID(String PID) 
    { 
     String taskID = OurGenerator.orgPID(PID); 
     return taskID; 
    } 
    Connection con; 
    PreparedStatement pstmt; 
    BufferedReader bf; 
    MyThread1(Connection con,PreparedStatement pstmt){ 
     this.con=con; 
     this.pstmt=pstmt; 
     try { 
      bf=new BufferedReader(new FileReader("D:/prod_review_sifid3.txt")); 
     }catch (IOException e) 
     { 
      System.out.println("IO Error Occurred: " + e.toString()); 
     } 
    } 
    public void run(){ 
     String line; 
     try{ 
      while ((line = bf.readLine()) != null) 
      { 
       String taskID = getTaskID(line); 
        pstmt.setString(1,taskID); 
        pstmt.setString(2,line); 
        pstmt.executeUpdate(); 

      } 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 
class MyThread2 extends Thread{ 
    public static String getTaskID(String PID) 
    { 
     String taskID = OurGenerator.orgPID(PID); 
     return taskID; 
    } 
    Connection con; 
    PreparedStatement pstmt; 
    BufferedReader bf; 
    MyThread2(Connection con,PreparedStatement pstmt){ 
     this.con=con; 
     this.pstmt=pstmt; 
     try { 
      bf=new BufferedReader(new FileReader("D:/sifid_review2.txt")); 
     }catch (IOException e) 
     { 
      System.out.println("IO Error Occurred: " + e.toString()); 
     } 
    } 
    public void run(){ 
     String line; 
     try{ 
      while ((line = bf.readLine()) != null) 
      { 
       String taskID = getTaskID(line); 
        pstmt.setString(1,taskID); 
        pstmt.setString(2,line); 
        pstmt.executeUpdate(); 

      } 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

public class SifuuidInsert { 
    public static void main(String ar[])throws Exception{ 
     Class.forName("oracle.jdbc.driver.OracleDriver"); 
     Connection con=DriverManager.getConnection("","",""); 
     PreparedStatement pstmt=con.prepareStatement("update Taskdata set taskID=? where entryid=?"); 
     MyThread1 first=new MyThread1(con,pstmt); 
     first.start(); 
     MyThread2 second=new MyThread2(con,pstmt); 
     second.start(); 
    } 
} 
+1

這真的取決於你的'run()'方法發生了什麼。 –

+0

絃線; \t \t嘗試{ \t \t而((線= bf.readLine())!= NULL) \t { \t \t \t \t字符串sifID = getSIFID(線); //線指一個ID \t \t \t \t //我從一個文本文件中讀取了該ID,其中有3萬個ID存在 \t \t \t \t pstmt.setString(1,sifUUID); \t \t \t \t pstmt.setString(2,line); \t \t \t \t pstmt.executeUpdate(); \t \t \t \t \t } \t \t}趕上(例外五){ \t \t \t e.printStackTrace(); \t \t} – kunu

+0

您能否將代碼添加到您的問題中?這樣我們可以例如見範圍。 –

回答

-1

MultiTherading用於併發訪問,不用於時間和性能目的。你應該直接通過更新一些類似的記錄

嘗試批量更新
+0

是的,我也在想。但同樣的程序,如果我在5臺不同的機器上運行,那麼記錄更新速度更快,因爲它可能是多個進程。那麼我將如何在同一個程序中的一臺機器上做同樣的事情。 – kunu

+0

那麼在這種情況下,我同意bmargulies的回答。嘗試連接每個線程與數據庫的獨立連接。 –

0

第一:使用批量更新添加查詢和推入集的末尾,信息here (general)here (for oracle

二:你只是重複一個類實現對於新文件,只需爲接收文件路徑的類添加一個參數即可。

class MyThrea extends Thread { 
    public static String getTaskID(String PID) { 
     String taskID = OurGenerator.orgPID(PID); 
     return taskID; 
    } 

    Connection con; 
    BufferedReader bf; 

    MyThread1(Connection con, String path) { 
     this.con = con; 
     this.pstmt = pstmt; 
     try { 
      bf = new BufferedReader(new FileReader(path)); 
     } catch (IOException e) { 
      System.out.println("IO Error Occurred: " + e.toString()); 
     } 
    } 

    public void run() { 

     PreparedStatement pstmt = con.prepareStatement("update Taskdata set taskID=? where entryid=?"); 
     String line; 
     try { 
      while ((line = bf.readLine()) != null) { 
       String taskID = getTaskID(line); 
       pstmt.setString(1, taskID); 
       pstmt.setString(2, line); 
       pstmt.addBatch(); 
      } 

      pstmt.executeBatch(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 


public class SifuuidInsert { 
    public static void main(String ar[]) throws Exception { 
     Class.forName("oracle.jdbc.driver.OracleDriver"); 
     Connection con = DriverManager.getConnection("", "", ""); 
     MyThread first = new MyThread1(con, "path_to_file_1"); 
     first.start(); 
     MyThread second = new MyThread1(con, "path_to_file_2"); 
     second.start(); 
    } 
} 

它可以通過加載第一個文件,然後執行更新來改進。

0

數據庫更新的大部分工作都發生在服務器上。根據數據庫和特定服務器的配置,這可能有助於向服務器呈現多個工作流 - 或者可能會受到影響,或者根本不會改變性能。

但是,大多數情況下,除非每個線程都有自己的與數據庫的獨立連接,否則它將無濟於事。