Java并发编程-Synchronizers
来源:互联网 发布:行之愈笃 则知之益明 编辑:程序博客网 时间:2024/06/15 11:11
Latch,Semaphore,Barrier是java中的三大同步工具类。首先了解下他们的特性和应用场景:{ps:有些东西纯属个人理解,有不正确的地方请指教}
Latch(门闩):闭锁是一个同步工具类,可以延迟线程执行直到所有的线程都到达一个状态。
作用:
1、确保某个计算在其所需要的所有资源都初始化后再执行;
2、确保某个服务在其他所依赖的服务都执行完毕后再执行;
3、等个某个操作的所有参与者都准备就绪后再继续执行。
信号量:信号量用来控制同时访问资源和执行当前动作的线程个数
信号量应用场景:
1、实现资源池,如数据库连接池;
2、将任意collection 转换成有界的阻塞collection
3、单个信号量的Semaphore对象可以实现互斥锁,而且可以由一个线程锁定,另外一个线程释放,是解决死锁的一种方法
Barrier(障碍):Barrier等待一组活动都完成或者一组活动都开始后再执行线程的后续操作,如组织去公园,等人到齐了才出发
Barrier跟Latch区别:
1、Barrier的定义是所有线程都得到达同一点才能继续向下执行,Latch的定义是当Latch达到一个 临界(终点)状态时所有的线程才能获得往下执行的通道。
2、Latch是线程等待某个事件完成,Barrier是线程等待其他线程
3、个人理解觉得Latch是被动等待,Barrier是主动等待。Barrier等待方会被等待方是同一属性级别,都是线程。如自发组织旅游,所有人按约定 的时间,地点在同一个地方集合,先到的人等待其他人都到齐后再一起出发。Latch就像开会签到,开会前参与者先进行签到,当组织者等到所有参与者都签到
后再进入会议主题
下面是三种同步工具类的Demo以及测试代码:
Latch:
package cn.com.chp5.latch;import java.util.concurrent.CountDownLatch;/** * <th>Latch例子<th> * * <p> * 功能:通过CountDownLatch begin事件触发线程等待,当所有子线程全部准备就绪后再开始执行线程,当所有子线程执行完毕后的end触发主线程 * 整个功能完成记录所有子线程从就绪到执行完的执行时间记录 * <p> * * <p> * Latch(门闩):闭锁是一个同步工具类,可以延迟线程执行直到所有的线程都到达一个状态。 * 作用:1、确保某个计算在其所需要的所有资源都初始化后再执行; * 2、确保某个服务在其他所依赖的服务都执行完毕后再执行; * 3、等个某个操作的所有参与者都准备就绪后再继续执行。 * <p> * * @author tianxingjian <h1>date: 2014-01-16</h1> */public class LatchDemo {public Long runTask(int threadNum, final Runnable runnable) throws InterruptedException{final CountDownLatch begin = new CountDownLatch(1);final CountDownLatch end = new CountDownLatch(threadNum);for(int i = 0; i < threadNum; i++){Thread th = new Thread(){public void run(){try{begin.await();try {runnable.run();}finally{end.countDown();}}catch (InterruptedException e) {e.printStackTrace();}}};th.start();}Long beginSec = System.nanoTime();//begin 和end顺序千万不能写错,不然程序就死锁了。begin.countDown();end.await();Long endSec = System.nanoTime();return endSec - beginSec;}}
package cn.com.chp5.latch;import java.util.Random;public class LatchTest {private static final int count = 10;public static void main(String[] args) throws InterruptedException {System.out.println("进入主线程:。。。。。。");Long l = new LatchDemo().runTask(count, new TaskAction());System.out.println("工作线程执行时间:" + l);}}class TaskAction implements Runnable{@Overridepublic void run() {Random rand = new Random(1000);int count = rand.nextInt() + 1;for(int i = 0; i < count; i++){int result = i*i;}}}
Semaphore:
package cn.com.chp5.semaphore;import java.util.concurrent.Semaphore;/** * <th>Semaphore例子<th> * * <p> * 预期结果:线程可以启动多个,但是同时执行aquireAction的线程最多count个 * <p> * * <p> * 信号量作用:信号量用来控制同时访问资源和执行当前动作的线程个数 * 信号量应用场景:1、实现资源池,如数据库连接池; * 2、将任意collection 转换成有界的阻塞collection * 3、单个信号量的Semaphore对象可以实现互斥锁,而且可以由一个线程锁定,另外一个线程释放,是解决死锁的一种方法 * <p> * * @author tianxingjian <h1>date: 2014-01-16</h1> */public class SemaphoreDemo {private final Semaphore se;private int count;public SemaphoreDemo(int count){this.count = count;se = new Semaphore(count);} public void doAction(){System.out.println(Thread.currentThread() + "[准备申请信号量!]");aquireAction();System.out.println(Thread.currentThread() + "[准备释放信号量!]");releaseAction();}public void aquireAction(){ try { //acquire:获得;下面方法是获取信号量 se.acquire(); System.out.println(Thread.currentThread() + "[信号量申请成功,当前aquireAction()并发数为:" + (count - se.availablePermits()) + "]"); Thread.sleep((long)Math.random()*10000); } catch (InterruptedException e) { e.printStackTrace(); }}public void releaseAction(){se.release();System.out.println(Thread.currentThread() + "[信号量释放成功!]");}}
package cn.com.chp5.semaphore;public class SemaphoreTest {public static void main(String[] args) {final SemaphoreDemo seDemo = new SemaphoreDemo(3);int threadCount = 10;String []threadName = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"};for(int i = 0; i < threadCount; i++){Thread th = new Thread(new Runnable() {@Overridepublic void run() {seDemo.doAction();}}, threadName[i]);th.start();}}}
Barrier:
package cn.com.chp5.barrier;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * <th>Barrier例子<th> * * <p> * Barrier(障碍):Barrier等待一组活动都完成或者一组活动都开始后再执行线程的后续操作,如组织去公园,等人到齐了才出发 * Barrier跟Latch区别: 1、Barrier的定义是所有线程都得到达同一点才能继续向下执行,Latch的定义是当Latch达到一个 * 临界(终点)状态时所有的线程才能获得往下执行的通道。 * 2、Latch是线程等待某个事件完成,Barrier是线程等待其他线程 * 3、个人理解觉得Latch是被动等待,Barrier是主动等待。Barrier等待方会被等待方是同一属性级别,都是线程。如自发组织旅游,所有人按约定 * 的时间,地点在同一个地方集合,先到的人等待其他人都到齐后再一起出发。Latch就像开会签到,开会前参与者先进行签到,当组织者等到所有参与者都签到 * 后再进入会议主题 * <p> * * @author tianxingjian <h1>date: 2014-01-16</h1> */public class BarrierDemo {private final CyclicBarrier barrier;public BarrierDemo(int barCount, Runnable runnable){barrier = new CyclicBarrier(barCount, runnable);}public void doAction(String [] thNames){for(int i = 0; i < thNames.length; i++){Thread th = new Thread(new BTRunnable(), thNames[i]);System.out.println("线程【" + thNames[i] + "】初始化完毕!");th.start();}}class BTRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread() + "[阻塞前操作!]" + System.currentTimeMillis());try {barrier.await();Thread.sleep((long) (Math.random() * 1000));} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "[阻塞后操作!]" + System.currentTimeMillis());}}}
package cn.com.chp5.barrier;/** * <th>Barrier例子<th> * * <p>结果:改变BarrierDemo barrier = new BarrierDemo(5, new Runnable())中的参数5会发现“执行次数:”打印次数不一样,这是因为每有一组线程数量达到这个数时候就会往下执行,然后Barrier reset值,其他线程进入后重新组成一组线程通过这个Barrier。如果5改变为非thNames长度的因子,程序会阻塞,因为有最后一组线程数达不到这个值导致这些线程一直在等待状态 * <p> * * @author tianxingjian <h1>date: 2014-01-16</h1> */public class BarrierTest {private static String []thNames = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}; public static void main(String[] args) {BarrierDemo barrier = new BarrierDemo(5, new Runnable() {int count = 0;@Overridepublic void run() {System.out.println("执行次数: " + ++count);}});barrier.doAction(thNames);}}
- Java并发编程-Synchronizers
- 并发(九):检查死锁与Locked ownable synchronizers
- Java并发编程 并发容器
- JAVA并发编程--并发模式
- JAVA并发-并发编程概述
- java并发编程----并发模型
- 【Java并发编程】并发集合
- 【Java并发编程】并发编程大合集
- 【Java并发编程】并发编程大合集
- 【Java并发编程】并发编程大合集
- 【Java并发编程】并发编程大合集
- 【Java并发编程】并发编程大合集
- java并发编程-- 并发编程大合集
- Java并发编程-并发编程知识点总结
- 【Java并发编程】并发编程大合集
- 【Java并发编程】并发编程大合集
- 【Java并发编程】并发编程大合集 (r)
- 【Java并发编程】并发编程大合集
- 设计模式学习笔记
- poj 2763 Housewife Wind(树链剖分)
- Running a Remote Desktop on a Windows Azure Linux VM
- C和指针的复习系列一:第一章~第七章
- 每个线程都有一个堆栈那么,这个堆栈多大呢?
- Java并发编程-Synchronizers
- 在asp,php,perl,jsp等各种编码中的301重定向
- Android 应用集成 Zxing 扫描QRCode -- 调用外部库模式
- SQL Server一些繁琐事
- 未分类--Windows API--SafeArrayDestroy
- 关于SILVERLIGHT 打印和报表的研究一
- structs +hibernate 通过Action 将前台数据存入数据库 , 表单提交
- 未分类--Windows API--SafeArrayGetElement
- C++ floor函数