一、Semaphore
Semaphore:信号量,用于限制某段代码的并发数。当permits为1,相当于synchronized。
直接上代码:
/**
* test Semaphore
* 信号量,用于限制某段代码的并发数。
* 当N为1,相当于synchronized
*/
private void threadTest5() {
final int permits = 3;
final Semaphore semaphore = new Semaphore(permits);
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for (int i = 0; i < 5; i++) {
threadPool.submit(new Runnable() {
@Override
public void run() {
try {
//获得许可
semaphore.acquire();
Log.i(TAG, "run: 剩余许可 = " + semaphore.availablePermits());
Thread.sleep(2000);
//释放许可
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
结果如下,前三条几乎同时打印,后两条是2000ms后打印,可见并发数就是permits值。
07-15 22:39:44.218 6810-7087/com.hfy.demo00 I/MainActivityhfy: run: 剩余许可 = 2
07-15 22:39:44.220 6810-7088/com.hfy.demo00 I/MainActivityhfy: run: 剩余许可 = 1
07-15 22:39:44.221 6810-7090/com.hfy.demo00 I/MainActivityhfy: run: 剩余许可 = 0
07-15 22:39:46.220 6810-7089/com.hfy.demo00 I/MainActivityhfy: run: 剩余许可 = 0
07-15 22:39:46.222 6810-7091/com.hfy.demo00 I/MainActivityhfy: run: 剩余许可 = 1
二、CyclicBarrier
CyclicBarrier,循环栅栏,n个线程都await了,才会 各自 继续往下走。(计数器可被重置后使用)
/**
* 循环栅栏 CyclicBarrier
* 大家都await了,才各自继续走。
*/
private void threadTest6() {
final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
Log.i(TAG, "run: 线程全都cyclicBarrier.await()了, 那大家都可以继续往下走了~");
}
});
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 4; i++) {
final int finalI = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
// int numberWaiting = cyclicBarrier.getNumberWaiting();
// Log.i(TAG, "run: i="+ finalI + ",numberWaiting = "+ numberWaiting);
Log.i(TAG, "run: i=" + finalI + ",我睡1s了,cyclicBarrier.await()");
cyclicBarrier.await();
Log.i(TAG, "run: i=" + finalI + ",继续往下走了~");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
}
}
结果如下,0、1、2都await了(阻塞了),然后各自都可以继续往下走了。
07-15 22:47:19.888 8140-8235/com.hfy.demo00 I/MainActivityhfy: run: i=2,我睡1s了,cyclicBarrier.await()
07-15 22:47:19.888 8140-8233/com.hfy.demo00 I/MainActivityhfy: run: i=0,我睡1s了,cyclicBarrier.await()
07-15 22:47:19.888 8140-8234/com.hfy.demo00 I/MainActivityhfy: run: i=1,我睡1s了,cyclicBarrier.await()
run: 线程全都cyclicBarrier.await()了, 那大家都可以继续往下走了~
run: i=1,继续往下走了~
07-15 22:47:19.889 8140-8233/com.hfy.demo00 I/MainActivityhfy: run: i=0,继续往下走了~
07-15 22:47:19.890 8140-8235/com.hfy.demo00 I/MainActivityhfy: run: i=2,继续往下走了~
07-15 22:47:19.891 8140-8236/com.hfy.demo00 I/MainActivityhfy: run: i=3,我睡1s了,cyclicBarrier.await()
三、CountDownLatch
CountDownLatch,闭锁,我(们) 等(await) 你们都countDown了,才往下走。
/**
* 闭锁 CountDownLatch
* 我(们)await你们都countDown了,才往下走
*/
private void threadTest7() {
final CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 5; i++) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
final int finalI = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
Log.i(TAG, "run: i=" + finalI + ",countDown了");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
try {
Log.i(TAG, "threadTest7: 主线程开始等待~");
latch.await();
Log.i(TAG, "threadTest7: 主线程继续走了~");
} catch (
InterruptedException e)
{
e.printStackTrace();
}
}
结果如下:
07-15 22:52:27.064 8684-8684/com.hfy.demo00 I/MainActivityhfy: threadTest7: 主线程开始等待~
07-15 22:52:28.064 8684-8970/com.hfy.demo00 I/MainActivityhfy: run: i=2,countDown了
07-15 22:52:28.064 8684-8969/com.hfy.demo00 I/MainActivityhfy: run: i=1,countDown了
07-15 22:52:28.064 8684-8968/com.hfy.demo00 I/MainActivityhfy: run: i=0,countDown了
07-15 22:52:28.065 8684-8684/com.hfy.demo00 I/MainActivityhfy: threadTest7: 主线程继续走了~
07-15 22:52:28.065 8684-8972/com.hfy.demo00 I/MainActivityhfy: run: i=4,countDown了
07-15 22:52:28.066 8684-8971/com.hfy.demo00 I/MainActivityhfy: run: i=3,countDown了