Semaphore
首先我们来看看Semaphore,中文名称信号量
我们来看看它的最常使用的方式
Semaphore semaphore = new Semaphore(1);
我们通过这个构造方法,传进去一个int
型变量,这就是通过这个int
型变量,来限制线程所能使用的资源,当我们通过semaphore.acquire();
方法来阻塞线程的执行,比如我下面这种情况
public class demo1 {
Semaphore semaphore1 = new Semaphore(1);
Semaphore semaphore2 = new Semaphore(0);
Semaphore semaphore3 = new Semaphore(0);
public void m1() throws InterruptedException {
semaphore1.acquire();
System.out.println("第一执行");
semaphore2.release();
}
public void m2() throws InterruptedException {
semaphore2.acquire();
System.out.println("第二执行");
semaphore3.release();
}
public void m3() throws InterruptedException {
semaphore3.acquire();
System.out.println("第三执行");
}
}
我使用三个线程来分别执行这三个方法,怎么保证执行顺序呢?这就可以使用信号量来解决
我们定义了三个信号量同时竞争一个资源,当竞争到资源的线程才可以往下执行方法,要不然会一直阻塞在semaphore1.acquire();
,还有就是我semaphore1获取资源执行完方法之后,如果是调用semaphore1.release()
来释放资源,会造成一个后果,也就是semaphore2和semaphore3都可以竞争资源,就容易造成乱序,所以semaphore1在执行完方法后,需要调用semaphore2的release()
来释放资源,这样只有semaphore2能通过semaphore2.acquire();
来获取资源了
也就是可以规定下一个获取资源的信号量是谁,保证了执行顺序
CyclicBarrier
中文译为屏障,举个例子吧,有一辆车可以坐30人,当所有人都到了上车之后车才可以开走,它是可以循环调用的,也就是说一辆车走后,还有车等着,再来30人之后车才开走,不断循环
CyclicBarrier通过await()
方法阻塞线程,如果人数不够,就会阻塞,每调用一次await()
,就会加一人,当到达设置的人数时,则执行下面的方法
CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
cyclicBarrier.await();
CountDownLatch
内部维护了一个计数器,类似倒计时那样的形式,我们预先设置一个值,当我们调用一次countDown()
方法计时器减1,我们使用await()
阻塞线程,当计时器变为0时,调用await()
阻塞的线程才会变为非阻塞,继续执行下去