一、闭锁
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 实现了一个拦截和同步的机制。