您现在的位置是:主页 > news > 传媒网站设计公司/北京seo公司wyhseo
传媒网站设计公司/北京seo公司wyhseo
admin2025/5/22 10:53:31【news】
简介传媒网站设计公司,北京seo公司wyhseo,莱芜搜狗推广提供,山东最新消息JAVA并发包中有三个类用于同步一批线程的行为,分别是CountDownLatch、Semaphore和CyclicBarrier。 CountDownLatch CountDownLatch是一个计数器闭锁,主要的功能就是通过await()方法来阻塞住当前线程,然后等待计数器减少到0了,再…
JAVA并发包中有三个类用于同步一批线程的行为,分别是CountDownLatch、Semaphore和CyclicBarrier。
CountDownLatch
CountDownLatch是一个计数器闭锁,主要的功能就是通过await()方法来阻塞住当前线程,然后等待计数器减少到0了,再唤起这些线程继续执行。 这个类里主要有两个方法,一个是向下减计数器的方法:countdown(),其实现的核心代码如下:
public boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; }
}
很简单,如果取得当前的状态为0,说明这个锁已经结束,直接返回false;如果没有结束,然后去设置计数器减1,如果compareAndSetState不成功,则继续循环执行。 而其中的一直等待计数器归零的方法是await()。
通过CountDownLatch可以做几件事情:
- 主线程控制同时启动一组线程
final CountDownLatch count = new CountDownLatch(1);
for (int i = 0; i < 3; i++) {new Thread("Thread" + i) {public void run() {System.out.println(Thread.currentThread().getName() + " wait");try {count.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " start");}}.start();
}
//等等三秒,否则有可能3个线程并没有全部进行await状态
try {Thread.sleep(3000);
} catch (InterruptedException e) {e.printStackTrace();
}
count.countDown();
- 主线程等待各子线程全部执行完毕后再往下执行:
final CountDownLatch count = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {new Thread("Thread" + i) {public void run() {System.out.println(Thread.currentThread().getName() + " start");count.countDown();}}.start();
}
try {count.await();
} catch (InterruptedException e) {e.printStackTrace();
}
System.out.println("All end!!!");
Semaphore
Semaphore与CountDownLatch相似,不同的地方在于Semaphore的值被获取到后是可以释放的,并不像CountDownLatch那样一直减到底。它也被更多地用来限制流量,类似阀门的 功能。如果限定某些资源最多有N个线程可以访问,那么超过N个主不允许再有线程来访问,同时当现有线程结束后,就会释放,然后允许新的线程进来。有点类似于锁的lock与 unlock过程。相对来说他也有两个主要的方法:
用于获取权限的acquire(),其底层实现与CountDownLatch.countdown()类似;
用于释放权限的release(),其底层实现与acquire()是一个互逆的过程。
用Semaphore来实现限流代码详见:semaphore例子
CyclicBarrier
CyclicBarrier是用来一个关卡来阻挡住所有线程,等所有线程全部执行到关卡处时,再统一执行下一步操作,它里面最重要的方法是await()方法,其实现如下:
private int dowait(boolean timed, long nanos)throws InterruptedException, BrokenBarrierException,TimeoutException {//取锁,以防止在后面做减1计数时线程不安全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();}//如果当前线程执行到了,则将计数器减1,计数器为0则说明所有线程均执行到这里,可以调用下一步操作int index = --count;if (index == 0) { // trippedboolean ranAction = false;try {//获取到定义好的下一步操作,并执行final Runnable command = barrierCommand;if (command != null)command.run();ranAction = true;nextGeneration();return 0;} finally {if (!ranAction)breakBarrier();}}// loop until tripped, broken, interrupted, or timed outfor (;;) {try {if (!timed)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 <= 0L) {breakBarrier();throw new TimeoutException();}}} finally {lock.unlock();}
}
即每个线程执行完后调用await(),然后在await()里,线程先将计数器减1,如果计数器为0,则执行定义好的操作,然后再继续执行原线程的内容。
这个类比之前两个类的一个好处是有点类似于切面编程,可以让我们在同类线程的某个切面切入一块逻辑,并且可以同步所有的线程的执行速度。
例子代码如下:
final CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {@Overridepublic void run() {System.out.println("All Threads Here");}
});
for (int i = 0; i < 4; i++) {new Thread("Thread" + i) {public void run() {System.out.println(Thread.currentThread().getName() + " wait");try {barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " crossed");}}.start();
}
最终的输出结果为:
Thread0 wait
Thread1 wait
Thread2 wait
Thread3 wait
All Threads Here
Thread0 crossed
Thread1 crossed
Thread2 crossed
Thread3 crossed