第一节 CountDownLatch

(1)初识CountDownLatch

(2)详述CountDownLatch

  CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1,当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

CountDownLatch中主要方法如下:

  public CountDownLatch(int count),构造函数中的count(计数器)实际上就是闭锁需要等待的线程数量,这个值只能被设置一次,而且CountDownLatch没有提供任何机制去重新设置这个计数值。

  public void countDown(),每调用一次这个方法,在构造函数中初始化的count值就减1,通知机制是此方法来完成的。

  public void await() throws InterruptedException,调用此方法的当前线程会一直阻塞,直到计时器的值为0。

(3)CountDownLatch示例

package com.test;import java.util.concurrent.CountDownLatch;public class CountDownLatchDemo{public static void main(String args[]) throws Exception{CountDownLatch latch = new CountDownLatch(3);Worker worker1 = new Worker("Jack 程序员1",latch);Worker worker2 = new Worker("Rose 程序员2",latch);Worker worker3 = new Worker("Json 程序员3",latch);worker1.start();worker2.start();worker3.start();latch.await();System.out.println("Main thread end!");}static class Worker extends Thread {private String workerName;private CountDownLatch latch;public Worker(String workerName,CountDownLatch latch) {this.workerName = workerName;this.latch = latch;}@Overridepublic void run() {try {System.out.println("Worker:"+workerName +" is begin.");Thread.sleep(1000L);System.out.println("Worker:"+workerName +" is end.");} catch (InterruptedException e) {// TODO Auto-generated catch block
                e.printStackTrace();}//模仿干活;
            latch.countDown();}}
}

上述程序运行结果如下:

Worker:Rose 程序员2 is begin.
Worker:Json 程序员3 is begin.
Worker:Jack 程序员1 is begin.
Worker:Jack 程序员1 is end.
Worker:Json 程序员3 is end.
Worker:Rose 程序员2 is end.
Main thread end!

从结果上可以看出,MainThread执行到latch.await();处会阻塞在该处,直到三个线程均完成的时候MainThread才会继续往下执行

(4)参考资料

本小节只是简单描述了CountDownLatch的使用方式等,欲了解其实现机制,可以查看下面的几篇文章

A、http://blog.itpub.net/30024515/viewspace-1432825/

B、http://www.tuicool.com/articles/mQnAfq

第二节 CyclicBarrier

(1)初识CyclicBarrier

(2)CyclicBarrier示例

应用场景:在某种需求中,比如一个大型的任务,常常需要分配很多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候就可以选择CyclicBarrier了。

示例:

package com.test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo{public static void main(String args[]) throws Exception{CyclicBarrier barrier = new CyclicBarrier(3,new TotalTask());BillTask worker1 = new BillTask("111",barrier);BillTask worker2 = new BillTask("222",barrier);BillTask worker3 = new BillTask("333",barrier);worker1.start();worker2.start();worker3.start();System.out.println("Main thread end!");}static class TotalTask extends Thread {
public void run() {System.out.println("所有子任务都执行完了,就开始执行主任务了。");}}static class BillTask extends Thread {private String billName;private CyclicBarrier barrier;public BillTask(String workerName,CyclicBarrier barrier) {this.billName = workerName;this.barrier = barrier;}@Overridepublic void run() {try {System.out.println("市区:"+billName +"运算开始:");Thread.sleep(1000L);//模仿第一次运算;System.out.println("市区:"+billName +"运算完成,等待中...");barrier.await();//假设一次运算不完,第二次要依赖第一次的运算结果。都到达这个节点之后后面才会继续执行;System.out.println("全部都结束,市区"+billName +"才开始后面的工作。");} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}}

上述程序运行结果如下:

市区:111运算开始:
市区:333运算开始:
Main thread end!
市区:222运算开始:
市区:333运算完成,等待中...
市区:222运算完成,等待中...
市区:111运算完成,等待中...
所有子任务都执行完了,就开始执行主任务了。//这句话是最后到达wait()方法的那个线程执行的
全部都结束,市区111才开始后面的工作。
全部都结束,市区222才开始后面的工作。
全部都结束,市区333才开始后面的工作。

解说:在这个示例中,构造CyclicBarrier时,传入了内部类TotalTask(TotalTask继承了Thread,是Runnable的实现)的实例对象,其意义在于:当所有的线程都执行到wait()方法时,它们会一起返回继续自己的工作,但是最后一个到达wait()方法的线程会执行TotalTask的run()方法;如果在构造构造CyclicBarrier时没有传入Runnable的实现对象作为构造参数,则当所有的线程都执行到wait()方法时会直接一起返回继续自己的工作。

(3)CyclicBarrier与CountDownLatch的区别

A、CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待;
B、CountDownLatch的计数器无法被重置;而CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。

第三节 Semaphore

(1)初识Semaphore

  Java中的Semaphore用于在线程间传递信号,从概念上讲,信号量维护了一个许可集合,Semaphore只对可用的许可进行计数,并采取相应的行动。信号量常常用于多线程的代码中,比如数据库连接池。

(2)Semaphore示例

场景:假设一个服务器资源有限,任意某一时刻只允许3个人同时进行访问,这时一共来了10个人

package com.test;
import java.util.concurrent.Semaphore;
public class SemaphoreDemo{public static void main(String args[]) throws Exception{final Semaphore semaphore = new Semaphore(3);//一次只运行3个人进行访问for(int i=0;i<10;i++) {final int no = i;Runnable thread = new Runnable() {public void run (){try {System.out.println("用户"+no+"连接上了:");Thread.sleep(300L);semaphore.acquire();//获取接下去执行的许可System.out.println("用户"+no+"开始访问后台程序...");Thread.sleep(1000L);//模仿用户访问服务过程semaphore.release();//释放允许下一个线程访问进入后台System.out.println("用户"+no+"访问结束。");} catch (InterruptedException e) {e.printStackTrace();}}};new Thread(thread).start();}System.out.println("Main thread end!");}
}

上述代码运行结果如下:

用户1连接上了:
用户3连接上了:
用户4连接上了:
用户2连接上了:
用户0连接上了:
用户5连接上了:
用户7连接上了:
Main thread end!
用户6连接上了:
用户8连接上了:
用户9连接上了:
用户3开始访问后台程序...
用户4开始访问后台程序...
用户2开始访问后台程序...
用户4访问结束。
用户3访问结束。
用户7开始访问后台程序...
用户0开始访问后台程序...
用户8开始访问后台程序...
用户2访问结束。
用户5开始访问后台程序...
用户0访问结束。
用户7访问结束。
用户1开始访问后台程序...
用户8访问结束。
用户6开始访问后台程序...
用户1访问结束。
用户9开始访问后台程序...
用户5访问结束。
用户6访问结束。
用户9访问结束。

从结果上可以看出来,10个人同时进来,但是只能同时3个人访问资源,释放一个允许进来一个

(3)参考资料

http://ifeve.com/semaphore/

第四节 Exchanger

(1)初识Exchanger

此处的Exechanger与前面描述的几个同步机制不一样,前面描述的几个同步机制均是通过计数器来实现的,下面简单描述一下Exechanger,看看Exchanger的应用场景:

注意:从上文描述,我们知道Exchanger用于在成对出现的线程之间(两个线程共有一个Exchanger)交换数据

(2)Exechanger示例

(3)参考资料

http://www.cnblogs.com/davidwang456/p/4179488.html

转载于:https://www.cnblogs.com/studyLog-share/p/5296449.html

java并发:线程同步机制之计数器Exechanger相关推荐

  1. Java高级-线程同步机制实现

    2019独角兽企业重金招聘Python工程师标准>>> 前言 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Threa ...

  2. java thirteen线程同步机制

    2019独角兽企业重金招聘Python工程师标准>>> 解决资源共享问题的方法一般是在指定时间段内只允许一个线程访问共享资源,这时就需要给共享资源上一道锁,比如售票员售票,当一个售票 ...

  3. 对Java多线程编程的初步了解,实现多线程的三种方式以及多线程并发安全的线程同步机制

    什么叫进程?什么叫线程? 进程相当于一个应用程序,线程就是进程中的一个应用场景或者说是一个执行单元,一个进程可以启动多个线程,每个线程执行不同的任务,一个线程不能单独存在,他必须是进程的一部分,当进程 ...

  4. Java多线程之线程同步机制(锁,线程池等等)

    Java多线程之线程同步机制 一.概念 1.并发 2.起因 3.缺点 二.三大不安全案例 1.样例一(模拟买票场景) 2.样例二(模拟取钱场景) 3.样例三(模拟集合) 三.同步方法及同步块 1.同步 ...

  5. 学习java的第四十天,线程的优先级、守护线程、线程同步机制、死锁

    一.线程的优先级(priority) Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行. 线程的优先级用数字表示,范围1~10 Thr ...

  6. Java多线程的同步机制(synchronized)

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...

  7. JAVA中线程同步的方法(7种)汇总

    JAVA中线程同步的方法(7种)汇总 同步的方法: 一.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法. ...

  8. 解析JVM线程同步机制

    http://blog.csdn.net/thl789/article/details/566494 对多线程的支持一般是在OS级的,而Java将其做在了语言级别,这其中最吸引人的莫过于Java对线程 ...

  9. JAVA中线程同步的几种实现方法

    JAVA中线程同步的几种实现方法 一.synchronized同步的方法: 1.synchronized同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁, ...

最新文章

  1. 京医通如何删除临时卡,解绑
  2. sql注入之order by猜列数问题
  3. 一个跨国银行的敏捷转型案例要点之Agile Center
  4. 《统计学习方法》代码更新了-(github的star数5300+)
  5. 突然讨厌做前端,讨厌代码_有关互联网用户最讨厌的广告类型的新数据
  6. 训练日志 2018.11.14
  7. libvirt热迁移报Connection refused错误解决办法
  8. 华为手机浏览器不支持PUT提交方式的解决方案
  9. asp.net页生命周期
  10. React脚手架开发
  11. 路面坑洼检测中的视觉算法
  12. python爬虫获取试题(仅提供逻辑和部分代码,不提供完整实例)
  13. bzoj2101:[USACO2010 DEC]TREASURE CHEST 藏宝箱
  14. QTableWidget 设置表头颜色
  15. css设置背景颜色/背景图像/背景图像平铺/背景图像位置/背景图像固定显示/综合设置元素背景的方法(学习笔记)
  16. Thread类实现多线程
  17. win10下安装多个JDK配置方法
  18. 【项目重构】总结与反思
  19. MySql 系列三:事务
  20. STM32f103xxxxz中断理解笔记

热门文章

  1. 数据结构—树(大纲)
  2. [蓝桥杯]试题 基础练习 龟兔赛跑预测
  3. 目录遍历及敏感信息泄露原理及案例(实验操作)
  4. Region proposal学习笔记
  5. matlab eps是什么
  6. 图像平均池化 利用pytorch对图像进行池化
  7. 用法getline(cin,a)和cin.getline(a,20) 能将空格输出
  8. 吴恩达神经网络和深度学习-学习笔记-42-目标检测
  9. python系列文章(基础,应用,后端,运维,自动化测试,爬虫,数据分析,可视化,机器学习,深度学习系列内容)
  10. 电磁场中场点和源点及▽(R)▽(1/R)▽.▽(1/R)