四 Java多线程-ThreadPool线程池-2( 二 )

这样就清晰多了 。
其中 , 最主要是要清楚几种workQueue , 也就是BlockingQueue<Runnable>的作用 。
SynchronousQueue同步队列 , 这个队列没有所谓的缓冲 , 这样做是为了排除阻塞时队列丢消息的可能 。如果没有其他微服务并行执行的话 , 可以放心地用这个队列 , 不然还是小心一点为妙 。它的示例代码:
/** * 同步队列 */public class SynchronousQueueTest {public static void main(String[] args) {ExecutorService service = new ThreadPoolExecutor(1,// 当要处理的线程数超过maximumPoolSize时 , 抛出异常2,1000,TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());for (int i = 0; i < 10; i++) {service.execute(() ->System.out.println("当前线程 " + Thread.currentThread().getName()));}service.shutdown();}}ArrayBlockingQueue , 它的使用范围非常广 , 一般可以用于轻量级的同步锁 , 也就是在同一个服务中(也就是非微服务架构) , 如果要具有分布式锁的功能又不想部署zookeeper这么麻烦的话 , ArrayBlockingQueue就是一个非常不错的选择 。
/** * 有界阻塞队列 */public class ArrayBlockingQueueTest {public static void main(String[] args) {ExecutorService service = new ThreadPoolExecutor(// 要处理的线程数超过maximumPoolSize+ workQueue.SIZE时 , 抛出异常1,2,1000,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());// 因为 maximumPoolSize(2) + ArrayBlockingQueue.SIZE(10) < 13 , 所以会抛出异常for (int i = 0; i < 13; i++) {service.execute(() ->System.out.println("当前线程 " + Thread.currentThread().getName()));}service.shutdown();}}再来看看ArrayBlockingQueue的另一个例子 , 可以加深印象:
public class ArrayBlockingQueueTester {public static BlockingQueue<String> queue = new ArrayBlockingQueue<String>(5);// 一个往里放class Producer implements Runnable {@Overridepublic void run() {try {queue.put("川菜");System.out.println(Thread.currentThread().getName() + " 厨师做好 川菜");} catch (InterruptedException e) {e.printStackTrace();}}}// 一个往外拿class Consumer implements Runnable {@Overridepublic void run() {try {String food = queue.take();System.out.println(Thread.currentThread().getName() + " 客人消费 " + food);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {// 客人等着菜for (int i = 0; i < 5; i++) {new Thread(new ArrayBlockingQueueTester().new Consumer()).start();}// 厨师做好菜for (int i = 0; i < 5; i++) {new Thread(new ArrayBlockingQueueTester().new Producer()).start();}}}ArrayBlockingQueue说白了就是一个往里放 , 一个往外拿:

1、往里放的 , 只能最多放指定个数就不能再放了(阻塞 , 等待 , 这里是5个);
2、往外拿的 , 如果没有可以拿的了 , 就等着(阻塞 , 等待) 。
咱们点菜的时候不就是这样吗?
LinkedBlockingQueue这个就牛逼了 , 相当于无底洞 , 有多少处理多少 , 此时线程池能够创建的最大线程数是corePoolSize , 而maximumPoolSize就成了摆设 , 这等于说是完全取决于系统的性能 。
/** * 无界阻塞队列 */public class LinkedBlockingQueueTest {public static void main(String[] args) {// 要处理的线程数过大时 , 是否抛出异常 , 取决于机器的性能ExecutorService service = new ThreadPoolExecutor(1,2,1000,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());for (int i = 0; i < 10000; i++) {service.execute(() ->System.out.println("当前线程 " + Thread.currentThread().getName()));}service.shutdown();}}

经验总结扩展阅读