JUC锁框架——join方法、CountDownLatch、CyclicBarrier和Semaphore

有用于同步一批线程的行为,分别是CountDownLatch、Semaphore和CyclicBarrier。

join方法

    // Thread.java中也有一个类似的基础方法
    public final synchronized void join(long millis) throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;
        if (millis == 0) {
            while (isAlive())
                wait(0);
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

如下实际案例中,如果有两个以上的线程,同步的顺序就受限于代码顺序了。

public static void main(String[] args) throws ParseException, InterruptedException{
    JoinTest worker0 = new JoinTest("worker0", 5000);  
    JoinTest worker1 = new JoinTest("worker1", 5000);  
    JoinTest worker2 = new JoinTest("worker2", 5000);  

    worker0.start();  
    worker1.start();  

    worker0.join();  
    worker1.join();  
    System.out.println("准备工作就绪");  

    worker2.start();    
}

CountDownLatch

  • void await()
    使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
  • boolean await(long timeout, TimeUnit unit)
    使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
  • void countDown()
    递减锁存器的计数,如果计数到达零,则释放所有等待的线程。

CyclicBarrier

  • CyclicBarrier(int parties)
    创建一个新的CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但不会在启动 barrier 时执行预定义的操作。
  • CyclicBarrier(int parties, Runnable barrierAction)
    创建一个新的CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。
  • int | await()
    在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
  • int | await(long timeout,
    TimeUnit unit) 在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。

CountDownLatch与CyclicBarrier二者的区别

CountDownLatch CyclicBarrier
计算减为0时释放所有等待的线程 计数加到指定值时释放所有等待线程
计数为0时,无法重置 计数达到指定值时,计数置为0重新开始
用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞
不可重复利用 可重复利用
阻塞主体是外部(当前)线程 阻塞主体是多个线程

Semaphore

Semaphore是对一定数量的资源进行管理的信号量,当Semaphore(1)时,退化为互斥锁。

  • acquire( int permits ) 中的参数是什么意思呢?可以这么理解, new Semaphore(6) 表示初始化了 6个通路,
  • semaphore.acquire(2) 表示每次线程进入将会占用2个通路,semaphore.release(2) 运行时表示归还2个通路。没有通路,则线程就无法进入代码块。
  • semaphore.acquire() + semaphore.release() 在运行的时候,其实和 semaphore.acquire(1) + semaphore.release(1) 效果是一样的。

你可能感兴趣的:(#,JUC)