博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发-6-wait、notify、Semaphore、CountDownLatch、CyclicBarrier
阅读量:6458 次
发布时间:2019-06-23

本文共 4110 字,大约阅读时间需要 13 分钟。

wait()、notify()和notifyAll()是Object类中的方法:

  为什么wait()等方法是在Object中而不是Thread中呢?

  同理,wait(),notify()是对等待这个Object(锁)的线程进行阻塞,唤醒等操作的,当然也要放在Object中

  假设,wait(),notify()放在Thead中,那么Thread可能等待很多个锁,操作起来也很复杂

  如果调用某个对象的wait()方法,当前线程必须拥有这个对象的monitor(即锁),因此调用wait()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)

  调用某个对象的wait()方法,相当于让当前线程交出此对象的monitor,然后进入等待状态,等待后续再次获得此对象的锁(Thread类中的sleep方法使当前线程暂停执行一段时间,从而让其他线程有机会继续执行,但它并不释放对象锁)

  同样地,调用某个对象的notify()方法,当前线程也必须拥有这个对象的monitor,因此调用notify()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)

进阶一信号量

  Java 提供了经典信号量(Semaphore)的实现,通过控制一定数量的允许(permit)的方式,来达到限制通用资源访问的目的。   你可以想象一下这个场景,在车站、机场等出租车时,当很多空出租车就位时,为防止过度拥挤,调度员指挥排队,等待坐车的队伍一次进来5个人上车, 等这5个人坐车出发,再放进去下一批 当信号量的大小为1时,与synchronized没有区别

public class SemaphoreTest {    private static Semaphore semaphore = new Semaphore(5);    public static void main(String[] args) {        for (int i = 0; i < 10; i++) {            new CarWorker(semaphore).start();        }    }}class CarWorker extends Thread {    private Semaphore semaphore;    public CarWorker(Semaphore semaphore) {        this.semaphore = semaphore;    }    @Override    public void run() {        try {            out.println(Thread.currentThread() + " waiting permitted");            semaphore.acquire();            out.println(Thread.currentThread() + " on car !");            Thread.sleep(10000);        } catch (Exception e) {        } finally {            out.println(Thread.currentThread() + " release permitted");            semaphore.release();        }    }}复制代码

进阶-CountDownLatch

  一次性使用的计数器,当CountDownLatch中数值为0时,所有await的线程得到唤醒   特别适合于A线程需要等待B和C线程的结果作为参数的这种场景   

public class CountDownLatchTest {    public static void main(String[] args) {        CountDownLatch countDownLatch = new CountDownLatch(6);        for (int i = 0; i < 5; i++) {            new FirstBatchPassenger(countDownLatch).start();        }        for (int i = 0; i < 5; i++) {            new SecondBatchPassenger(countDownLatch).start();        }        while (countDownLatch.getCount() != 1) {            try {                Thread.sleep(1000);            } catch (InterruptedException e) {            }        }        out.println("MainThread countDown!");        countDownLatch.countDown();    }}class FirstBatchPassenger extends Thread {    private CountDownLatch countDownLatch;    public FirstBatchPassenger(CountDownLatch countDownLatch) {        this.countDownLatch = countDownLatch;    }    @Override    public void run() {        out.println("FirstBatchPassenger Executed!");        countDownLatch.countDown();    }}class SecondBatchPassenger extends Thread {    private CountDownLatch countDownLatch;    public SecondBatchPassenger(CountDownLatch countDownLatch) {        this.countDownLatch = countDownLatch;    }    @Override    public void run() {        try {            countDownLatch.await();            out.println("SecondBatchPassenger Executed!");        } catch (InterruptedException e) {        }    }}复制代码

输出:

FirstBatchPassenger Executed!FirstBatchPassenger Executed!FirstBatchPassenger Executed!FirstBatchPassenger Executed!FirstBatchPassenger Executed!MainThread countDown!SecondBatchPassenger Executed!SecondBatchPassenger Executed!SecondBatchPassenger Executed!SecondBatchPassenger Executed!SecondBatchPassenger Executed!复制代码

进阶三-CyclicBarrier

触发屏障,当await自动达到屏障数量时,触发屏障操作。可重复使用!

public class CyclicBarrierTest {    public static void main(String[] args) {        CyclicBarrier cyclicBarrier = new CyclicBarrier(2, () -> out.println("Action GO!"));        for (int i = 0; i<6;i++){            new CyclicBarrierWorker(cyclicBarrier).start();        }    }}class CyclicBarrierWorker extends Thread {    private CyclicBarrier cyclicBarrier;    public CyclicBarrierWorker(CyclicBarrier cyclicBarrier) {        this.cyclicBarrier = cyclicBarrier;    }    @Override    public void run() {        out.println("Executed!");        try {            cyclicBarrier.await();        } catch (InterruptedException e) {        } catch (BrokenBarrierException e) {        }    }}复制代码

输出:

Executed!Executed!Executed!Action GO!Executed!Action GO!Executed!Executed!Action GO!复制代码

转载地址:http://qiizo.baihongyu.com/

你可能感兴趣的文章
【转】github如何删除一个仓库
查看>>
Linux系统编程——进程调度浅析
查看>>
大数据Lambda架构
查看>>
openCV_java 图像二值化
查看>>
状态模式
查看>>
删除CentOS / RHEL的库和配置文件(Repositories and configuraiton files)
查看>>
DJANGO变动库的一次真实手动经历
查看>>
VC++获得微秒级时间的方法与技巧探讨(转)
查看>>
HDOJ-1010 Tempter of the Bone
查看>>
MySQL my.cnf参数配置优化详解
查看>>
JavaNIO基础02-缓存区基础
查看>>
日本开设无人机专业,打造无人机“人才市场”
查看>>
190行代码实现mvvm模式
查看>>
PXE部署实例
查看>>
cobbler初探------实现自动安装centos6.4
查看>>
Android Studio 2.0 preview3 BUG
查看>>
兼容几乎所有浏览器的透明背景效果
查看>>
Go语言4
查看>>
jeesite 框架搭建与配置
查看>>
Adb移植(一)简单分析
查看>>