重入锁、公平锁、读写锁、CountDownLatch和CyclicBarrier

重入锁可以看成synchronized的增强版,可以完全替代synchronized关键字,可以使用JUC下的locks.ReentrantLock类实现。从命名可以看出,重入锁可以反复进入,使用中比较灵活,开发人员可以手动指定何时加锁,何时释放锁,对逻辑的控制远超过关键字synchronized,唯一值的注意的是,退出临界区必须要释放锁,否则,其他线程就没有机会再访问临界区
重入锁:可以提供中断响应,对于synchronized关键字,如果一个线程等待锁,要么获得锁继续执行,要么保持等待。但使用重入锁:
(1)可以使得线程中断。如果一个线程正在等待锁,它依然可以收到一个通知,被告知无需等待,可以停止,这对解决死锁还是有一定帮助的。
(2)限时等待,给定一个等待时间,让程序自动放弃。ReentrantLock.tryLock()方法可以带参数,就是等待一定时间,如果超过设定时间还没有获得锁就返回false,也可以不带参数,当前线程立即尝试获得锁,如果成功返回true,否则返回false。
(3)重入锁可以设置公平锁,顾名思义,多个线程请求锁时会按照发送请求的先后顺序来分配。构造函数:

public ReentrantLocal(boolean fair)

重入锁的好搭档:Condition
Condition对象与wait()和notify()方法大致相同,利用Condition对象可以让线程在合适的时间等待,或者在某一个特定的时刻得到通知。
Condition接口主要提供的方法有:
await()方法,使当前线程等待,同时释放当前锁,当使用signal()方法时,线程会重新获得锁继续执行(在signal()和await()方法执行前,线程必须拥有锁)。
读写锁
ReadWriteLock是JDK1.5提供的,读写分离锁可以有效的减少竞争,提高系统性能。在系统中,读操作的次数远远大于写的操作次数,读写锁可以发挥很大功能

倒计数器
CountDownLatch:主要是用来控制线程等待,可以让某一个线程等待直到倒计数结束,再开始执行。

public CountDownLatch(int count)

参数即为当前计数器的计数个数。

public class CountDownLatchDemo implements Runnable {
    static CountDownLatch end = new CountDownLatch(10);
    static CountDownLatchDemo demo = new CountDownLatchDemo();
    @Override
    public void run() {
        try {
            Thread.sleep(new Random().nextInt(10)*1000);
            System.out.println("check complete");
            end.countDown();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
//两种写法
    public static void main(String[] args) throws Exception{
//        ExecutorService exec = Executors.newFixedThreadPool(10);
//        for(int i=0;i<10;i++){
//            exec.submit(demo);
//        }
        Thread[] threads = new Thread[10];
        for(int i=0;i<10;i++){
            threads[i] = new Thread(demo,"thread"+i);
            threads[i].start();
        }
        end.await();
        System.out.println("fire");
       // exec.shutdown();
    }
}

主线程在CountDownLatch上等待,当所有的检查任务都完成后,主线程继续。

循环栅栏
CyclicBarrier也是一种线程并发控制工具,也可以实现线程间的计数等待。比CountDownLatch功能强大一些,可以接收一个参数作为barrierAction。所谓barrierAction就是当计数器一次计数完成后,系统会执行的动作。

public class CyclicbarrierDemo {
    public static class Soldier implements Runnable{
        private String soldier;
        private final CyclicBarrier cyclicBarrier;

        Soldier(CyclicBarrier cyclicBarrier,String soldierName){
            this.cyclicBarrier =cyclicBarrier;
            this.soldier = soldierName;
        }
        @Override
        public void run() {
            try {
                //等待所有士兵到齐
                cyclicBarrier.await();
                doWork();
                //等待所有士兵完成工作
                cyclicBarrier.await();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        void doWork(){
            try {
                Thread.sleep(Math.abs(new Random().nextInt()%10000));
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println(soldier+":完成任务");
        }
    }
    public static class BarrierRun implements Runnable{
        boolean flag;
        int N;
        public BarrierRun(boolean flag, int N){
            this.flag = flag;
            this.N = N;
        }

        @Override
        public void run() {
            if(flag){
                System.out.println("司令:[士兵"+N+"个,完成任务");
            }else {
                System.out.println("司令:[士兵"+N+"个,集合完毕");
                flag = true;
            }
        }
    }

    public static void main(String[] args) {
        final int N = 10;
        Thread[] allSoldier = new Thread[N];
        boolean flag = false;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(N,new BarrierRun(flag,N));
        System.out.println("集合队伍");
        for(int i=0;i<N;++i){
            System.out.println("士兵"+i+"报道");
            allSoldier[i] = new Thread(new Soldier(cyclicBarrier,"士兵"+i));
            allSoldier[i].start();
        }
    }
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值