CountDownLatch
类似计数器,倒数到0,门闩打开,否则一直await阻塞。如下:线程1和线程2,线程1必须等线程2打印完,才能打印;线程2打印完,调用latch.countdown(),计数器减一。 初始化参数,看业务倒数几次。
关键方法:
latch.await();
latch.countDown();
public static void main(String[] args) {CountDownLatch latch = new CountDownLatch(1);char[] c1 = new char[]{'1','2','3','4','5'};char[] c2 = new char[]{'A','B','C','D','E'};new Thread(()->{try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Arrays.toString(c1));},"t1").start();new Thread(()->{System.out.println(Arrays.toString(c2));latch.countDown();},"t2").start();}
CyclicBarrier
循环栅栏,当定义的线程都完成了某种操作,栅栏才打开,只要有一个线程没跑完,栅栏也不会打开。new CyclicBarrier的第1个参数是参与的线程个数,第2个参数是所有线程都完成后下一步需要做的任务。
区别CountDownLatch:
① CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的;
② CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。
public static void main(String[] args) {CyclicBarrier barrier = new CyclicBarrier(5, ()->{System.out.println("完成最后的任务");});for (int i = 0; i < 5; i++) {int tempInt = i;new Thread(()->{try {System.out.println("线程 "+ tempInt +" 抵达战场");barrier.await();System.out.println("线程 " + tempInt +" 结束");} catch (Exception e) {e.printStackTrace();}}).start();}}
Semaphore
信号量,只是控制访问某些资源的线程数量,注意:只是控制线程个数,它不能保证线程安全哦。
public static void main(String[] args){Semaphore semaphore = new Semaphore(3); //模拟3个车位for(int i=1;i<=6;i++){ //模拟6部车new Thread(()->{try{semaphore.acquire();System.out.println(Thread.currentThread().getName()+"\t抢到车位");try{TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"\t停车3秒后离开车位");} catch (InterruptedException e){e.printStackTrace();} finally {semaphore.release();}},String.valueOf(i)).start();}}
LockSupport
它是用于创建锁和其他同步类的基本线程阻塞原语,它的构造方法是私有,不可以实例化。简言之就是:当调用park方法就阻塞住当前线程,当调用unPark方法,就把传入的线程唤醒 。
/*** @title: LockSupport* @description: 交替输出1A2B3C* @author: l* @date: 2021/08/04 19:18*/public class T_04TestLockSupport {static Thread t1 = null;static Thread t2 = null;public static void main(String[] args) {char[] c1 = "12345".toCharArray();char[] c2 = "ABCDE".toCharArray();t1 = new Thread(()->{for (char c : c1){System.out.println(c);LockSupport.unpark(t2);LockSupport.park();}});t2 = new Thread(()->{for (char c : c2){LockSupport.park();System.out.println(c);LockSupport.unpark(t1);}});t1.start();t2.start();}}
