【问题标题】:Where to use Multi threading concept在哪里使用多线程概念
【发布时间】:2016-11-22 11:58:25
【问题描述】:

我有一个要求更新数据库中可用的 300 000 条记录。当我编写一个独立程序时,它需要 25-30 分钟来更新 5 000 条记录。所以完成所有记录可能需要 30 个小时。然后我想我会写一个多线程程序。我创建了 2 个线程,然后开始更新,它花费了相同的时间意味着 5k 条记录需要 30 分钟。

据我所知,我们正在使用线程来并发访问一个方法,在这种情况下它不会加速更新。

对于上述情况,我必须做些什么来减少时间。而多线程的实际用途是什么

   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();
  }
}

【问题讨论】:

  • 这真的取决于你的 run() 方法中发生了什么。
  • 字符串行; try{ while (( line = bf.readLine()) != null) { String sifID = getSIFID(line);//lines 表示一个 id //我从一个有 30 万个 id 的文本文件中读取该 id pstmt .setString(1,sifUUID); pstmt.setString(2,line); pstmt.executeUpdate(); } }catch(异常 e){ e.printStackTrace(); }
  • 能否将代码添加到您的问题中?这样我们可以例如见范围。
  • 嗨 @mad_manny 我添加了代码
  • 每个线程都应该获得自己的连接并创建/使用自己的预处理语句。否则,在最好的情况下,线程在驱动程序处停止,在更坏的情况下,程序有未定义的行为 - 崩溃、部分更新、数据库数据损坏等。

标签: java multithreading


【解决方案1】:

首先:使用批量更新添加查询并在集合末尾推送,Infohere (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();
    }
}

可以通过先加载文件,然后执行更新来改进。

【讨论】:

    【解决方案2】:

    数据库更新的大部分工作发生在服务器上。根据特定服务器的数据库和配置,它可能有助于为服务器提供多个工作流——或者它可能会受到伤害,或者它可能根本不会改变性能。

    然而,大多数情况下,除非每个线程都有自己独立的数据库连接,否则它无济于事。

    【讨论】:

      【解决方案3】:

      MultiTherading 用于并发访问,而不是用于时间和性能目的。您应该通过更新一些类似的记录来尝试直接批量更新

      【讨论】:

      • 是的,我也这么想。但是如果我在 5 台不同的机器上运行相同的程序,那么记录的更新速度会更快,因为它可能是多个进程。那么我将如何在同一程序中的一台机器上做同样的事情。
      • 那么在这种情况下,我同意 bmargulies 的回答。尝试连接每个线程与数据库的独立连接。
      猜你喜欢
      • 2013-09-07
      • 2012-12-10
      • 1970-01-01
      • 2018-12-18
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多