Semaphoer
很简单的工具类,目前我也只是在限流的场景使用过。简单搞个例子看下吧。
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 20, TimeUnit.SECONDS, new LinkedBlockingDeque<>(200));
//搞5个信号量
private static Semaphore semaphore = new Semaphore(5);
public static void doSomething(String people) {
try {
semaphore.acquire(1);
Thread.sleep(10000);
System.out.println(people + "拿到令牌,打钱完成 ==============" );
System.out.println(System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
} finally {
semaphore.release(1);
}
}
public static void main(String[] args) throws InterruptedException {
{
String people = "人";
int i= 0;
for ( int j= 0;j<10 ; j++) {
i++;
int finalI = i;
executor.execute(() -> doSomething(people+ finalI));
}
}
}
*人3拿到令牌,打钱完成 ==============
人4拿到令牌,打钱完成 ==============
1643961091811
人1拿到令牌,打钱完成 ==============
1643961091811
人2拿到令牌,打钱完成 ==============
1643961091811
人7拿到令牌,打钱完成 ==============
1643961091811
1643961091811*
**人8拿到令牌,打钱完成 ==============
1643961101818
人10拿到令牌,打钱完成 ==============
1643961101818
人6拿到令牌,打钱完成 ==============
1643961101818
人9拿到令牌,打钱完成 ==============
1643961101818
人5拿到令牌,打钱完成 ==============
1643961101818**
Semaphore源码
大致上与ReentrantLock类似,因为内部都是实现AQS。
不同的地方就是,Semaphore是加的共享锁。
释放锁这有点不太一样。注意看下会唤醒后续多个线程
在这里插入图片描述
CountDownLatch
CountDownLatch的主要适用两种场景:
1:让多个线程等待。
2:让单个线程等待。
举2个代码例子吧
//士兵等号令才能吃饭
static CountDownLatch countDownLatch = new CountDownLatch(1);
static ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
public static void main(String[] args) {
int i = 0;
for (; ; ) {
i++;
int finalI = i;
executor.execute(() -> {
System.out.println("士兵" + finalI + "等吃饭");
try {
countDownLatch.await();
System.out.println("吃饭吧");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
if (i == 5) {
countDownLatch.countDown();
System.out.println("可以吃饭");
break;
}
}
}
//所有士兵打完游戏才能吃饭
public static void gameEnd() throws InterruptedException {
int i = 0;
for (; ; ) {
i++;
int finalI = i;
executor.execute(() -> {
System.out.println("士兵" + finalI + "打游戏");
countDownLatch1.countDown();
System.out.println("士兵" + finalI +"打完了");
});
if (i == 5) break;
}
countDownLatch1.await();
System.out.println("可以吃饭");
}