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);}}



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脚走路磨起泡了怎么办 脚趾头磨了个泡怎么办 脚趾头起了大泡怎么办 脚上有脚气起水泡很痒怎么办 脚底有水泡很痒怎么办 脚底磨得起泡了怎么办 脚底有水泡很疼怎么办 脚底硬皮走路疼怎么办 上火鼻子上长脓包怎么办 鼻子上总是长脓包怎么办 孕妇脚上长水泡很痒怎么办 脚气有水泡很痒怎么办 脚又痒又脱皮怎么办 手指出水泡很痒怎么办 鼻子里上火长泡怎么办 鼻子又干又痒怎么办 眼皮长了小水泡怎么办 眼皮上长了个泡怎么办 眼皮上长了粉刺怎么办 上眼皮又肿又疼怎么办 眼皮长了个痘怎么办 手指上小水泡痒怎么办 阴茎长了一个泡怎么办 干活累的腰疼怎么办 手长白色的小泡怎么办 全身长水泡很痒怎么办 自吸泵声音大怎么办 索尼镜头盖丢了怎么办 15-45镜头盖丢了怎么办 手机镜头盖丢了怎么办 三星微单镜头盖怎么办 大胸走路容易抖怎么办 哎呦该怎么办是什么歌 老婆想爆我菊花怎么办 衣服泡了一晚上怎么办? 来大姨妈了该怎么办 耳机戴不住总掉怎么办 眼睛被辣椒辣了怎么办 电信光猫复位后怎么办 电信光猫重置了怎么办 u盘无法安全弹出怎么办