NIO之锁

一、闭锁

CountDownLatch:线程递减锁也叫闭锁。
当所有的锁都已经解开的时候,再进行下一步操作。一般的使用方法是将闭锁封装进一个线程对象中,通过构造方法传入某个线程对象中。然后线程成功执行一次,调用一次countDown()方法,闭锁减一。
它通过await方法来产生阻塞。

创建闭锁:
创建一个闭锁,在创建的时候需要指定一个初始容量

CountDownLatch cdl =new CountDownLatch(2);

锁递减:
每次调用这个countDown方法的时候,闭锁的数量都会减1

cdl.countDown();

锁阻塞:
当锁未释放时,就一直产生阻塞。当锁的数量递减为0时,锁释放

cdl.await();

例如:
主函数:

public static void main(String[] args) throws Exception {
    CountDownLatch cdl =new CountDownLatch(2);
    new Thread(new BuyFood(cdl)).start();
    new Thread(new BuyPot(cdl)).start();
    cdl.await();
    System.out.println("开始炒菜");
}

BuyFood类:

class BuyFood implements Runnable{
    private CountDownLatch cdl;
    public BuyFood(CountDownLatch cdl) {
        this.cdl=cdl;
    }

    @Override
    public void run() {
        System.out.println("菜买回来了");
        cdl.countDown();
    }
}

BuyPot类:

class BuyPot implements Runnable{
    private CountDownLatch cdl;
    public BuyPot(CountDownLatch cdl) {
        this.cdl=cdl;
    }
    @Override
    public void run() {
        System.out.println("锅买回来了");
        cdl.countDown();
    }
}

只有当线程买锅和买菜都执行完成之后,再进行炒菜的操作。

二、栅栏锁

通过以栅栏的形式,达到一个同步的效果。当所有线程都准备好的时候,再进行下一步操作。使用方法是将这个栅栏锁作为对象的一个属性,通过构造方法传入这个栅栏锁对象。调用await来产生阻塞,这个栅栏锁对象锁的数量为0时,锁放开。
想象赛马的场景,当所有马都就绪后才开始比赛。
它身上有一个await方法,来达到阻塞的效果。
主函数:

public static void main(String[] args) {
    CyclicBarrier cb = new CyclicBarrier(2);
    new Thread(new Horse(cb)).start();
    new Thread(new Horse2(cb)).start();
}

Horse类:

class Horse implements Runnable {
    private CyclicBarrier cb;

    public Horse(CyclicBarrier cb) {
        this.cb = cb;
    }

    @Override
    public void run() {
        System.out.println("赛马1来到了栅栏前");
        //await()方法会产生阻塞,阻塞放开的条件是初始数量减为0
        //此外,await每调用一次,初始容量就会减1
        try {
            cb.await();
        } catch (Exception e) {
            e.printStackTrace();
        } 
        System.out.println("赛马1开始跑");
    }
}

Horse2类:

class Horse2 implements Runnable {
    private CyclicBarrier cb;

    public Horse2(CyclicBarrier cb) {
        this.cb = cb;
    }

    @Override
    public void run() {
        System.out.println("赛马2正在处理肚子问题");
        try {
            Thread.sleep(3000);
            System.out.println("赛马2来到栅栏前");
            //通过栅栏实现了一个线程的同步机制
            cb.await();
            System.out.println("赛马2开始跑");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

发现赛马1到栅栏,赛马2开始处理拉肚子问题,赛马2到,然后才开始比赛跑。
通过这个栅栏锁CyclicBarrier 实现了一个拦截和同步的机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值