• 【Java线程】使用十个线程往某表插值,允许并发数5,执行完毕后让计数线程去统计数量。


    【前言】

    这是实际工作中某任务的简化版,实际任务是将A库a表的数据迁移到B库b表,需要启动多线程进行迁移,全部迁移完毕后更改某表某记录的状态和数量字段。

    例程进行了简化处理以方便理解。

    【实现】

    利用固定线程池限流,利用CoutDownLatch来通知计数线程进行统计。

    【代码】

    数据库实用类:

    package com.hy.lab.countdown;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class DbUtil {
        public static Connection getConnection() {
            Connection conn = null;
            try {
                Class.forName("oracle.jdbc.driver.OracleDriver");
                String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
                String user = "luna";
                String pass = "1234";
                conn = DriverManager.getConnection(url, user, pass);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }
    }

    插值线程:

    package com.hy.lab.countdown;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.concurrent.CountDownLatch;
    
    public class InsertThread implements Runnable{
        private int min;
        private int max;
        private CountDownLatch cdl;
    
        public InsertThread(int min,int max,CountDownLatch cdl){
            this.min=min;
            this.max=max;
            this.cdl=cdl;
        }
    
        @Override
        public void run() {
            String insertSql="insert into emp69(id,name) values (?,?)";
            try(Connection conn=DbUtil.getConnection();
                PreparedStatement pstmt =conn.prepareStatement(insertSql)){
                conn.setAutoCommit(false);
    
                for(int i=min;i<max;i++){
                    pstmt.setLong(1,i);
                    pstmt.setString(2,"Name:"+i);
                    pstmt.addBatch();
                }
    
                pstmt.executeBatch();
                conn.commit();
    
                cdl.countDown();
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }

    计数线程:

    package com.hy.lab.countdown;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.concurrent.CountDownLatch;
    
    public class Counter extends Thread{
        private CountDownLatch cdl;
    
        public Counter(CountDownLatch cdl){
            this.cdl=cdl;
        }
    
        public void run(){
            try {
                cdl.await();
                printTotal();
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        private void printTotal(){
            String sql="select count(*) from emp69";
            try(Connection conn=DbUtil.getConnection();
                PreparedStatement pstmt =conn.prepareStatement(sql);
                ResultSet rs=pstmt.executeQuery()){
    
                while(rs.next()){
                    int count=rs.getInt(1);
                    System.out.println("多线程插值后emp69表总数="+count);
                    return;
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }

    使用代码:

    package com.hy.lab.countdown;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Test {
        public static void main(String[] args){
            final int TH_COUNT=10;// 线程数10
            CountDownLatch cdl=new CountDownLatch(TH_COUNT);
            new Counter(cdl).start();
    
            ExecutorService es= Executors.newFixedThreadPool(5);// 并发数5
    
            for(int i=0;i<TH_COUNT;i++){
                int min=i*100;
                int max=(i+1)*100;
                es.submit(new InsertThread(min,max,cdl));
            }
    
            es.shutdown();
        }
    }

    【运行情况】

    多线程插值后emp69表总数=1000

    【使用到的表结构】

    create table emp69(
        id number(12),
        name nvarchar2(20),
        primary key(id));

    【参考资料】

    《Java多线程与线程池计数详解》 肖海鹏 牟东旭著 清华大学出版社出版

    END

  • 相关阅读:
    HTTP 和 HTTPS
    HTTP 协议
    基础查询
    python编程从入门到实践笔记
    python-32-类的组合与初识继承
    python-31-初识面向对象与自定义类
    python-30-异常处理
    python-29-模块与包导入
    python-28-序列化模块
    python-27-其他常用模块(二)
  • 原文地址:https://www.cnblogs.com/heyang78/p/16359276.html
Copyright © 2020-2023  润新知