java并发工具类
2021-03-29 09:27
标签:共享 tps tac 方法 ant get nan eem thread 字面意思: 入参是一个计数器的值,当一个线程执行完毕时调用 大家都玩过王者荣耀的 结果 字面意思: 第一个入参代表屏障接触时阻塞线程的数量。第二个入参代表屏障解除时要进行的操作 该类同样可以实现与 结果 字面意思: 入参对象是一个许可的数量,如果 接着王者荣耀排位 结果 同一时刻只有两个player获取到打野位置(共享资源)符合预期。 java并发工具类 标签:共享 tps tac 方法 ant get nan eem thread 原文地址:https://www.cnblogs.com/geekdc/p/13610451.html一、CountDownLatch
倒计时锁闩
,该类可以实现一个线程在等其他多个线程执行完之后,继续执行。countDown()
方法,计数器值会减1
,当计数器值为0
时,被await()
阻塞的线程将被唤醒。CountDownLatch latch = new CountDownLatch(10);
5V5
排位吧,当己方5个人准备就绪,对方5人也准备就绪时,才可以进入B/P
环节,也就是王者荣耀这个线程需要等待10位玩家的线程都准备完毕,然后才出发进入游戏的操作。package com.duchong.concurrent;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* 模拟5V5排位,10个玩家都准备就绪,才开始进入游戏
* CountDownLatch :阻塞主线程,等子线程完成
* @author DUCHONG
* @since 2020-09-03 17:43:13
*/
public class CountDownLatchDemo {
public static final int playerNum=10;
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(10);
GameThread subThread = new GameThread(latch);
try {
//模拟5V5排位
for (int i = 1; i
二、CyclicBarrier
循环屏障
,多个线程到达一个屏障点时被阻塞,直到最后一个线程到达屏障点时,屏障才会解除,所有被屏障拦截的线程继续运行。CyclicBarrier c = new CyclicBarrier(10, ()->System.out.println("屏障解除"));
await()
方法其实是调用Condition
的await()
public class CyclicBarrier {
/** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();
//....省略
public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen
}
}
//wait方法
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
//重入锁
final ReentrantLock lock = this.lock;
//加锁
lock.lock();
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
int index = --count;
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
// 循环
for (;;) {
try {
if (!timed)
// 调用condition的await()方法
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We‘re about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
}
if (g.broken)
throw new BrokenBarrierException();
if (g != generation)
return index;
if (timed && nanos
CountDownLatch
相同的效果package com.duchong.concurrent;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
/**
* 模拟5V5排位,10个玩家都准备就绪,才开始进入游戏
* CyclicBarrier :阻塞子线程,当等待中的子线程数到达一定数量时,跳闸。
* @author DUCHONG
* @since 2020-09-03 17:41:35
*/
public class CyclicBarrierDemo {
public static final int playerNum=10;
/**
* 屏障,初始10 当await()的线程数量达到10时,跳闸。
*/
static CyclicBarrier c = new CyclicBarrier(playerNum, ()->System.out.println("王者荣耀:玩家全部准备就绪,开始进入游戏"));
public static void main(String[] args) {
try {
//
for (int i = 1; i
三、Semaphore
信号量
,多个线程访问一个共享资源时,如果想控制对该资源访问的线程的数量,可以用这个工具类。数量大于1
,则可以作为共享锁
来使用,如果数量等于1
,则可以作为排他锁
来使用acquire()
方法表示得到一个许可,可以对共享资源进行操作, 如果许可数量分配完了,其他线程将阻塞, 直到已得到许可的线程释放许可后,才有机会再获取许可。release()
方法表示释放一个许可。Semaphore semaphore=new Semaphore(5);
5V5
的例子来讲,当玩家进入B/P
环节,5个人,但是地图只有上中下三路,也就是说最多2个人去打野位置package com.duchong.concurrent;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* 模拟进入5V5排位游戏后的B/P环节,五个人,上中下三路,最多2个人去打野位置
* Semaphore,对资源的并发数控制
* @author DUCHONG
* @since 2020-09-03 15:46
**/
public class SemaphoreDemo {
//打野人数
public static final int wildNum=2;
//总共人数
public static final int totalNum=5;
static Semaphore semaphore=new Semaphore(wildNum);
public static void main(String[] args) {
try {
for (int i = 1; i
下一篇:学习Python需要什么工具?