CountDownLatch
CountDownLatch的构造器:
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
count参数可以通俗的理解为countDown()方法调用的次数,当count和调用次数相同时,await()方法的线程才能继续执行。
注意:countDown()不一定是另一个线程调用。
CountDownLatch的示例:
package day3;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CountDownLatchTest {
private CountDownLatch c = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
CountDownLatchTest test = new CountDownLatchTest();
ExecutorService executor = Executors.newFixedThreadPool(2);
sumEven sumEven = test.new sumEven(1,100);
sumOdd sumOdd = test.new sumOdd(1,100);
executor.submit(sumEven);
executor.submit(sumOdd);
long start = System.currentTimeMillis();
System.out.println("等待结果");
test.c.await();
System.out.println("等待时间:"+(System.currentTimeMillis() - start));
System.out.println("偶数和:"+sumEven.getSumEven());
System.out.println("奇数和:"+sumOdd.getSumOdd());
executor.shutdown();
}
class sumEven implements Runnable{
private int start;
private int end;
private int sumEven;
public int getSumEven() {
return sumEven;
}
public void setSumEven(int sumEven) {
this.sumEven = sumEven;
}
public sumEven(int start,int end) {
this.start = start;
this.end = end;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sumEven = sumEvenM(start,end);
c.countDown();
}
public int sumEvenM(int start,int end) {
int sum = 0;
for(int i = start;i<=end;i++) {
if(i%2==0) {
sum = sum +i;
}
}
return sum;
}
}
class sumOdd implements Runnable{
private int start;
private int end;
private int sumOdd;
public int getSumOdd() {
return sumOdd;
}
public void setSumOdd(int sumOdd) {
this.sumOdd = sumOdd;
}
public sumOdd(int start,int end) {
this.start = start;
this.end = end;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sumOdd = sumOddM(start,end);
c.countDown();
}
public int sumOddM(int start,int end) {
int sum = 0;
for(int i = start;i<=end;i++) {
if(i%2==1) {
sum = sum +i;
}
}
return sum;
}
}
}
解释:此示例开启了俩个线程,分别用来算奇数和与偶数和,等待算完后打印出来。
console输出:
等待结果
等待时间:2001
偶数和:2550
奇数和:2500
应用场景:适用于最后需要统计结果的程序,但本人感觉这种功能可以直接用fork/join框架来处理
CyclicBarrier
感觉跟CountDownLatch差不错
Semaphore
控制线程的并发数,示例如下:
package day3;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class SemaphoreTest {
private static final int THREAD_COUNT = 30;
private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
private static Semaphore s = new Semaphore(10);
private static AtomicInteger j = new AtomicInteger(0);
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
s.acquire();
System.out.println("save data"+(j.incrementAndGet()));
TimeUnit.SECONDS.sleep(10);
s.release();
} catch (InterruptedException e) {
}
}
});
}
threadPool.shutdown();
}
}
执行结果是每十个线程并发执行。