zoukankan      html  css  js  c++  java
  • 一种父线程阻塞等待子线程的有效方法

           最近在做一个查询优化时,考虑到一次查询耗时较多,所以打算用多线程来做,之前是串行查询。比如一个用户查询触发50个线程,在只有一个用户的情况下,性能比串行查询确实提高了许多,但当多个用户同时触发查询的时候,CPU却飙高得很厉害,比串行查询好不了多少。

           因为一次查询是同步查询,即要等待所有的线程完成后才返回结果,所以一开始想到的办法是每次查询都起一个线程池,这个线程池里面有50个线程,这个线程池阻塞等待所有的线程完成然后返回结果,从而造成50个用户同时查询时起了50个线程池,cpu资源消耗殆尽。能不能做到所用用户查询触发的线程统一由一个线程池控制呢?百度后终于找到了解决办法。

     1 import java.util.concurrent.CountDownLatch;
     2 
     3 public class ThreadA implements Runnable {
     4 
     5     private CountDownLatch cDownLatch;
     6 
     7     private String name;
     8 
     9     public ThreadA(CountDownLatch cDownLatch, String threadName) {
    10         this.cDownLatch = cDownLatch;
    11         this.name = threadName;
    12     }
    13 
    14     @Override
    15     public void run() {
    16         System.out.println(name + " begin.");
    17         try {
    18             Thread.sleep(500);
    19         } catch (InterruptedException e) {
    20             e.printStackTrace();
    21         }
    22         System.out.println(name + " end.");
    23         cDownLatch.countDown();
    24     }
    25 }
    线程执行体
     1 import java.util.concurrent.BlockingQueue;
     2 import java.util.concurrent.LinkedBlockingQueue;
     3 import java.util.concurrent.ThreadPoolExecutor;
     4 import java.util.concurrent.TimeUnit;
     5 
     6 public class MyThreadPool extends ThreadPoolExecutor {
     7 
     8     private static MyThreadPool myPool = new MyThreadPool(10, 100, 1,
     9             TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>());
    10 
    11     private MyThreadPool(int corePoolSize, int maximumPoolSize,
    12             long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
    13         super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    14     }
    15 
    16     public static MyThreadPool getInstance() {
    17         return myPool;
    18     }
    19 }
    线程池
    import java.util.concurrent.CountDownLatch;
    
    public class MainThread {
        public static void main(String[] args) {
            ThreadExecutor executor = new ThreadExecutor("A", 3);
            executor.execute();
        }
    }
    
    class ThreadExecutor {
        private String prefix;
        private int size;
    
        public ThreadExecutor(String prefix, int size) {
            this.prefix = prefix;
            this.size = size;
        }
    
        public void execute() {
            System.out.println(prefix + " begin.");
            ThreadA temp = null;
            CountDownLatch cDownLatch = new CountDownLatch(size);
            for (int i = 0; i < size; i++) {
                temp = new ThreadA(cDownLatch, prefix + i);
                MyThreadPool.getInstance().execute(temp);
            }
            try {
                cDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(prefix + " end.");
        }
    }
    主线程

    执行结果

    A begin.
    A0 begin.
    A1 begin.
    A2 begin.
    A1 end.
    A0 end.
    A2 end.
    A end.

  • 相关阅读:
    解决ListView异步加载数据之后不能点击的问题
    android点击实现图片放大缩小 java技术博客
    关于 数据文件自增长 的一点理解
    RAC 实例不能启动 ORA1589 signalled during ALTER DATABASE OPEN
    Linux 超级用户的权利
    RAC 实例 迁移到 单实例 使用导出导入
    Shell 基本语法
    Linux 开机引导与关机过程
    RAC 实例不能启动 ORA1589 signalled during ALTER DATABASE OPEN
    Oracle RAC + Data Guard 环境搭建
  • 原文地址:https://www.cnblogs.com/BensonHe/p/3150516.html
Copyright © 2011-2022 走看看