zoukankan      html  css  js  c++  java
  • Java并发编程的艺术(九)——闭锁、同步屏障和信号量

    闭锁:CountDownLatch

    使用场景

    当前线程需要等待若干条线程执行完毕后,才能继续执行的情况。

    也可以是若干个步骤执行完毕后的情况。

    使用方法

    初始化闭锁的时候,填入计数值,然后等待其他线程或者步骤对计数值进行操作减减。当计数值变为0的时候,线程就会从闭锁的await()方法处继续执行。

    不能将计数值的参数设置为0,因为这样就毫无意义。

    使用示例

    // 初始化闭锁,并设置资源个数
    CountDownLatch c = new CountDownLatch(2);
    
    Thread t1 = new Thread( new Runnable(){
        public void run(){
            // 加载资源1
            loadSomething();
            // 本资源加载完后,计数值-1
            c.countDown();
        }
    } ).start();
    
    Thread t2 = new Thread( new Runnable(){
        public void run(){
            // 加载资源2
            loadSomething();
            // 本资源加载完后,计数值-1
            c.countDown();
        }
    } ).start();
    
    Thread t3 = new Thread( new Runnable(){
        public void run(){
            // 线程阻塞,等待计数值为0
            c.await();
            // 当闭锁计数值为0时,await返回,执行接下来的任务
            dosomething();
        }
    } ).start();
    

    同步屏障:CyclicBarrier

    作用

    让一组线程中的每一个线程达到一个位置的时候被阻塞,直到最后一个线程到达屏障,所有被阻塞的线程继续运行。

    与闭锁的区别

    • 闭锁只能阻塞一个线程,目的是为了让当个线程满足某种条件。
    • 同步屏障可以满足多个线程同时阻塞,并同时继续执行。

    使用方法

    在实例化同步屏障的时候,填入线程等待个数,当等待的线程数满足这个数值要求,同步屏障才会释放。

    使用示例

    // 实例化对象,填入需要等待的线程数和屏障开启的任务
    CyclicBarrier barrier = new CyclicBarrier(10, new Runnable(){
        public void run(){
            //当所有线程准备完毕后触发此任务
        }
    });
    
    // 启动10条线程
    for( int i=0; i < 10; i++ ) {
        new Thread( new Runnable() {
            public void run() {
                // 等待,(同步屏障数量-1,直到为0时,打开屏障)
                barrier.await();
    
                dosomething();
            }
        } ).start();
    }
    

    信号量:

    作用

    可以控制访问特定资源的线程数量。

    使用方法

    示例化对象的时候,填入最大可访问的线程数量。在获取资源之前,调用acquire,获取完毕之后,调用release。

    使用示例

    // 实例化信号量对象,设置最大访问线程参数为5
    Semaphore semaphore = new Semaphore(5);
    
    // 启动 10条线程
    for ( int i=0; i < 10; i++ ) {
        new Thread( new Runnbale(){
            public void run(){
                // 获取资源,若此时资源数值为0,则阻塞,当资源数大于0,则继续执行
                semaphore.acquire();
                // 任务代码
                soSomething();
                // 释放资源
                semaphore.release();
            }
        } ).start();
    }
    
  • 相关阅读:
    Kettle初使用
    Datax初使用
    代码层次上的软件质量属性
    第二周周总结
    软件质量属性---可修改性
    淘宝网中的软件质量属性
    第一周周总结
    2020寒假(12)
    2020寒假(11)
    2020寒假(10)
  • 原文地址:https://www.cnblogs.com/lippon/p/14117661.html
Copyright © 2011-2022 走看看