1. 怎么理解CountDownLatch?【内部也是AQS】
参照如上:线程1调用await阻塞。直到调用若干次的countDown后(具体次数,初始化的时候已经指定),才会唤醒继续
2. 如果多个线程前置调用await呢?
public class CountDownLatchDemo {
static CountDownLatch countDownLatch = new CountDownLatch(2);
public static void main(String[] args) {
new Thread(()->{
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t4");
}, "t4").start();
new Thread(()->{
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t5");
}, "t5").start();
new Thread(()->{
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1");
}, "t1").start();
new Thread(()->{
countDownLatch.countDown();
System.out.println("t2");
}, "t2").start();
new Thread(()->{
countDownLatch.countDown();
System.out.println("t3");
}, "t3").start();
}
}
打印结果:
t2
t3
t5
t4
t1
3. 如何理解Semaphore呢?【AQS相关-队列】
Semaphore初始化需要参数,有3个信号量。acquire表示申请一个许可
线程1、2、3申请完成后,线程4再来申请的话,就已经申请不到了,会被阻塞
如果:线程4、5、6都进入阻塞,同时现场1 release信号量,那么只会唤醒队列第一个4
4. 理解SemaphoreDemo
public class SemaphoreDemo {
static Semaphore semaphore = new Semaphore(2);
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1").start();
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t2").start();
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t3").start();
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t4").start();
Thread.sleep(1000);
semaphore.release();
}
}
打印结果:
t1
t2
t3