一、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了