使用多线程处理任务一定快吗

刚开始接触java的时候对多线程总是怀抱着好奇心,总想弄明白多线程的好处,为什么要使用多线程编程。甚至于认为使用多线程就比单线程要高大上、要好。但事实真的是这样吗?下面就举一个案列看看

1.使用ThreadPoolExecutor创建线程池(创建线程池有很多种方法,这里就不一一列举了)
/**
 * 线程池类
 */
public class CustomThreadPoolExecutor {

    private ThreadPoolExecutor pool = null;

    /**
     * 线程池初始化
     */
    public void initialize() {
        //ThreadPoolExecutor的构造函数接收4个参数:
        //corePoolSize     核心线程池大小
        //maximumPoolSize  最大线程池大小
        //keepAliveTime    最大存活时间
        //unit             eepAliveTime时间单位
        //workQueue        阻塞队列
        pool = new ThreadPoolExecutor(20, 50, 30,
                TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(10));
    }

    /**
     * 销毁线程池
     */
    public void destroy() {
        if(pool!=null) {
            pool.shutdown();
        }
    }

    /**
     * 获取线程池对象
     * @return
     */
    public ExecutorService getCustomThreadPoolExecutor() {
        return this.pool;
    }
}

2. 提供的业务数据类
/**
* 图书类
*/
public class Book implements Comparable<Book>{

    private String id; // id

    private String name; //书名

    private Long sales; //销量

//省略getter,setter 方法

    @Override
    public int compareTo(Book o) {
        Long diff = this.getSales() - o.getSales();

        if (diff > 0) {
            return 1;
        }else if(diff<0) {
            return -1;
        }
        return 0;
    }


public class ProvideBooks {

    /**
     * 获取图书集合
     * @return
     */
    public static List<Book> getBookList(){

        List<Book> bookList = new ArrayList<>();

        int l=4000;

        for (int i = 0; i < l; i++) {
            Random random = new Random();
            Book book=new Book();

            int sales= random.nextInt(100);

            book.setSales(Long.valueOf(sales));
            book.setId(UUID.randomUUID().toString().replace("-",""));
            book.setName("大江大河");
            bookList.add(book);
        }
        return bookList;
    }

}
3. 测试方法1-多线程并发执行
public class Main1 {

    public static void main(String[] args) {

        Long start=System.currentTimeMillis();

        QueryDao queryDao=new QueryDao();

        //获取 bookList
        List<Book> bookList = ProvideBooks.getBookList();

        // 每1000条数据开启一条线程
        int threadSize = 1000;

        // 总数据条数
        int dataSize = bookList.size();

        //System.out.println("书籍类别数:"+dataSize);

        // 线程数
        int threadNum = dataSize / threadSize + 1;

        System.out.println("线程数量:" + threadNum);

        // 定义标记,过滤threadNum为整数
        boolean special = dataSize % threadSize == 0;

        // 创建一个线程池
        CustomThreadPoolExecutor executor = new CustomThreadPoolExecutor();
        executor.initialize();

        ExecutorService pool = executor.getCustomThreadPoolExecutor();

        // 确定每条线程的数据
        List<Book>  cutList = null;

        // 分割bookList
        for (int i = 0; i < threadNum; i++) {
            if (i == threadNum - 1) {
                if (special) {
                    break;
                }
                cutList = bookList.subList(threadSize * i, dataSize);
            } else {
                cutList = bookList.subList(threadSize * i, threadSize * (i + 1));
            }

            final List<Book> compareList = cutList;

            //(放到线程池中,线程异步执行)
            pool.execute(new Runnable() {

                @Override
                public void run() {
                    //Collections.sort(compareList);

                    for (Book book : compareList) {
                        String sql = "insert into book(id,name,sales) values(?,?,?)";
                        int result = 0;

                        synchronized (queryDao){
                            if (queryDao.getConnection()) {
                                result = queryDao.executeUpdate(sql, book.getId(), book.getName(), book.getSales());
                            }
                        }

                        if(result>0){

                            //System.out.println("插入成功");
                        }
                    }

                }

            });


        }

        executor.destroy();//销毁

        while(true){
            if(pool.isTerminated()){

                System.out.println("所有的子线程都结束了!");
                break;
            }

        }

        Long end=System.currentTimeMillis();

        System.out.println("总共花费了--"+(end - start)/1000+"."+(end - start) % 1000 +"--s");


    }
}

结果如下:

4. 测试方法2-单线程执行
public class Main2 {

    public static void main(String[] args) {
        Long start = System.currentTimeMillis();

        QueryDao queryDao=new QueryDao();

        //获取 bookList
        List<Book> bookList = ProvideBooks.getBookList();

        // 总数据条数
        int dataSize = bookList.size();
        //System.out.println("书籍类别数:"+dataSize);
        
        int result=0;
        
        for(Book book:bookList){
            String sql="insert into book(id,name,sales) values(?,?,?)";
            if(queryDao.getConnection()){
                result=queryDao.executeUpdate(sql, book.getId(), book.getName(), book.getSales());
            }

            if(result>0){

                //System.out.println("插入成功");
            }
        }
        Long end = System.currentTimeMillis();
        
        System.out.println("总共花费了--" + (end - start) / 1000+"."+(end - start) % 1000 + "--s");
    }
}

结果如下:

结果分析

从上述结果中可以看出,多线程下竟然还比单线程慢了0.3秒左右。可见多线程下的效率并不一定比单线程的高。当然跟我的测试数据量也有一定的关系。有兴趣的可以看看《并发编程的艺术》这本书。我这里就不再阐述原因了。

转载于:https://www.cnblogs.com/codingdong/p/10252311.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值