CountDownLatch

首先先说明CountDownLatch辅助类

CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
主要方法
public CountDownLatch(int count);//构造方法参数指定了计数的次数
public void countDown();//当前线程调用此方法,则计数减一1
public void await() throws InterruptedException//调用此方法会一直阻塞当前线程,直到计时器的值为0
列子:

public class CountDownLatchDemo {final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static void main(String[] args) throws InterruptedException {CountDownLatch latch=new CountDownLatch(2);//两个工人的协作Worker worker1=new Worker("zhang san", 5000, latch);Worker worker2=new Worker("li si", 8000, latch);worker1.start();//worker2.start();//latch.await();//等待所有工人完成工作System.out.println("all work done at "+sdf.format(new Date()));}static class Worker extends Thread{String workerName; int workTime;CountDownLatch latch;public Worker(String workerName ,int workTime ,CountDownLatch latch){this.workerName=workerName;this.workTime=workTime;this.latch=latch;}public void run(){System.out.println("Worker "+workerName+" do work begin at "+sdf.format(new Date()));doWork();//工作了System.out.println("Worker "+workerName+" do work complete at "+sdf.format(new Date()));latch.countDown();//工人完成工作,计数器减一}private void doWork(){try {Thread.sleep(workTime);} catch (InterruptedException e) {e.printStackTrace();}}}}输出:
Worker zhang san do work begin at 2011-04-14 11:05:11
Worker li si do work begin at 2011-04-14 11:05:11
Worker zhang san do work complete at 2011-04-14 11:05:16
Worker li si do work complete at 2011-04-14 11:05:19
all work done at 2011-04-14 11:05:19

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。

注:什么叫线程安全?这个首先要明确。线程安全就是说多线程访问同一代码,不会产生不确定的结果。

并行和并发区别

1、并行是指两者同时执行一件事,比如赛跑,两个人都在不停的往前跑;
2、并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率

LinkedBlockingQueue
由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。

package cn.thread;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;/*** 多线程模拟实现生产者/消费者模型*  * @author 林计钦* @version 1.0 2013-7-25 下午05:23:11*/
public class BlockingQueueTest2 {/*** * 定义装苹果的篮子* */public class Basket {// 篮子,能够容纳3个苹果BlockingQueue<String> basket = new LinkedBlockingQueue<String>(3);// 生产苹果,放入篮子public void produce() throws InterruptedException {// put方法放入一个苹果,若basket满了,等到basket有位置basket.put("An apple");}// 消费苹果,从篮子中取走public String consume() throws InterruptedException {// take方法取出一个苹果,若basket为空,等到basket有苹果为止(获取并移除此队列的头部)return basket.take();}}// 定义苹果生产者class Producer implements Runnable {private String instance;private Basket basket;public Producer(String instance, Basket basket) {this.instance = instance;this.basket = basket;}public void run() {try {while (true) {// 生产苹果System.out.println("生产者准备生产苹果:" + instance);basket.produce();System.out.println("!生产者生产苹果完毕:" + instance);// 休眠300msThread.sleep(300);}} catch (InterruptedException ex) {System.out.println("Producer Interrupted");}}}// 定义苹果消费者class Consumer implements Runnable {private String instance;private Basket basket;public Consumer(String instance, Basket basket) {this.instance = instance;this.basket = basket;}public void run() {try {while (true) {// 消费苹果System.out.println("消费者准备消费苹果:" + instance);System.out.println(basket.consume());System.out.println("!消费者消费苹果完毕:" + instance);// 休眠1000msThread.sleep(1000);}} catch (InterruptedException ex) {System.out.println("Consumer Interrupted");}}}public static void main(String[] args) {BlockingQueueTest2 test = new BlockingQueueTest2();// 建立一个装苹果的篮子Basket basket = test.new Basket();ExecutorService service = Executors.newCachedThreadPool();Producer producer = test.new Producer("生产者001", basket);Producer producer2 = test.new Producer("生产者002", basket);Consumer consumer = test.new Consumer("消费者001", basket);service.submit(producer);service.submit(producer2);service.submit(consumer);// 程序运行5s后,所有任务停止
//        try {//            Thread.sleep(1000 * 5);
//        } catch (InterruptedException e) {//            e.printStackTrace();
//        }
//        service.shutdownNow();}}

ConcurrentLinkedQueue
ConcurrentLinkedQueue是Queue的一个安全实现.Queue中元素按FIFO原则进行排序.采用CAS操作,来保证元素的一致性。
LinkedBlockingQueue是一个线程安全的阻塞队列,它实现了BlockingQueue接口,BlockingQueue接口继承自java.util.Queue接口,并在这个接口的基础上增加了take和put方法,这两个方法正是队列操作的阻塞版本。

package cn.thread;import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ConcurrentLinkedQueueTest {private static ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();private static int count = 2; // 线程个数//CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。private static CountDownLatch latch = new CountDownLatch(count);public static void main(String[] args) throws InterruptedException {long timeStart = System.currentTimeMillis();ExecutorService es = Executors.newFixedThreadPool(4);ConcurrentLinkedQueueTest.offer();for (int i = 0; i < count; i++) {es.submit(new Poll());}latch.await(); //使得主线程(main)阻塞直到latch.countDown()为零才继续执行System.out.println("cost time " + (System.currentTimeMillis() - timeStart) + "ms");es.shutdown();}/*** 生产*/public static void offer() {for (int i = 0; i < 100000; i++) {queue.offer(i);}}/*** 消费*  * @author 林计钦* @version 1.0 2013-7-25 下午05:32:56*/static class Poll implements Runnable {public void run() {// while (queue.size()>0) {while (!queue.isEmpty()) {System.out.println(queue.poll());}latch.countDown();}}
}

运行结果:
costtime 2360ms

改用while (queue.size()>0)后
运行结果:
cost time 46422ms

结果居然相差那么大,看了下ConcurrentLinkedQueue的API原来.size()是要遍历一遍集合的,难怪那么慢,所以尽量要避免用size而改用isEmpty().

Java 阻塞线程用法相关推荐

  1. java阻塞线程池_线程池解决阻塞方法

    一.序言 当我们需要使用线程的时候,我们可以新建一个线程,然后显式调用线程的start()方法,这样实现起来非常简便,但在某些场景下存在缺陷:如果需要同时执行多个任务(即并发的线程数量很多),频繁地创 ...

  2. java 中断线程 wait_Java 线程中断(interrupt)与阻塞 (park)的区别

    很多Java开发人员(包括我),尤其是刚进入软件行业的新手,认为Java设置线程中断就是表示线程停止了,不往前执行了, Thread.currentThread().interrupt() 其实不是这 ...

  3. java让线程空转_Java锁:悲观/乐观/阻塞/自旋/公平锁/闭锁,锁消除CAS及synchronized的三种锁级别...

    JAVA LOCK 大全 [TOC] 一.广义分类:乐观锁/悲观锁 1.1 乐观锁的实现CAS (Compare and Swap) 乐观锁适合低并发的情况,在高并发的情况下由于自旋,性能甚至可能悲观 ...

  4. java 分析 线程堵塞 原因_java如何避免线程阻塞?相关方法解析

    最近有小伙伴在工作中遇到了java线程阻塞问题,面对这样的问题,大家束手无策,不知道从何下手,那么今天我们就给大家分享一些关于java避免线程阻塞的方法. 阻塞指的是暂停一个Java线程同步的执行以等 ...

  5. JAVA阻塞队列和线程池原理

    阻塞队列 队列 队列是一种特殊的线性表,遵循先入先出.后入后出的基本原则,一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作. 什么是阻塞队列 支持阻塞的插入方法,当队列满时,队列会阻 ...

  6. Java 如何线程间通信,面试被问哭。。。

    Java 如何线程间通信,曾经小编面试被问哭的一道题.. 正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及 ...

  7. java基础----线程

    一.进程与线程 进程(process)是一个可并发执行的具有独立功能的程序(program)关于某个数据集合的一次执行过程,也是操作系统进行资源分配和保护的基本单位. 线程(thread)是操作系统进 ...

  8. Java中线程池,你真的会用吗

    转载自   Java中线程池,你真的会用吗 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Ex ...

  9. Java基础——线程及并发机制

    前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...

最新文章

  1. 【剑指offer-Java版】21包含min函数的栈
  2. 在状态栏中插入类似进度条的可视控件
  3. SAP UI5 this.oModel.createBindingContext will trigger odata request
  4. minheight能继承吗_民法典亮点盘点 | 侄子能继承叔叔的遗产吗?
  5. 内存对齐分配策略(含位域模式)
  6. Python入门学习笔记(5)
  7. GCN实践——可视化cora-network
  8. 模拟CMOS 集成电路设计
  9. MacroSAN杭州宏杉科技存储使用小节
  10. 唐宇迪学习笔记6:线性回归算法原理推导
  11. Linux内核编程打印所有线程信息
  12. java zipentry 压缩率_java – ZipEntry.STORED用于已经压缩的文件?
  13. svn 安装教程 TortoiseSvn
  14. 微服务项目之电商4.0技术架构图
  15. 数据库及基本表的建立
  16. Filco圣手二代键盘蓝牙连接方法
  17. mysql查看分片键
  18. 红警游戏开源代码带给我们的震撼
  19. HTML 个人简历模板简易版
  20. 阿里测试工程师聊:软件测试需要学什么?

热门文章

  1. 搞笑但又真实无比! 59条和程序员相关的名人语录,哪一条让你感同身受?
  2. ncnn/net.h: No such file or directory的解决方法
  3. 五一名宿现涨价毁约潮会涨多少?没人订会降价吗?
  4. 多参加活动,生活才精彩
  5. 每日学术速递1.28
  6. 使用AWS的API Gateway实现websocket
  7. 刘海屏启动页全屏适配
  8. 1、常用激活函数:Sigmoid、Tanh、ReLU、LReLU、RReLU、ELU
  9. 笑出腹肌!有些程序员真会玩代码注释
  10. KL散度的计算及其相关问题题