• 一种父线程阻塞等待子线程的有效方法


           最近在做一个查询优化时,考虑到一次查询耗时较多,所以打算用多线程来做,之前是串行查询。比如一个用户查询触发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.

  • 相关阅读:
    深入 HBase 架构解析(2)
    [HEOI2012]朋友圈
    图论常用概念整理
    [COGS2175][SDOI2012]象棋-二分图最大权匹配
    KMP算法
    数据结构部分整理
    最小费用最大流学习笔记
    动态开点线段树
    Splay 模板
    C++ P1164 小A点菜
  • 原文地址:https://www.cnblogs.com/BensonHe/p/3150516.html
Copyright © 2020-2023  润新知