并发-6-wait、notify、Semaphore、CountDownLatch、CyclicBarrier

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!
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值