JUC包下各种类的用法
- CountDownLatch
适用场景举例:一个线程等待其他线程完成任务后再继续任务
门栓机制,维护一个变量,每次调用门栓的countdown()方法变量递减,直到减至0,线程从等待中释放。
public class CountdownLatchExample {
public static void main(String[] args) throws Exception{
CountDownLatch countDownLatch = new CountDownLatch(10);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i = 0; i < 10;i++) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread ID :" + Thread.currentThread().getId() + " run 1 times");
countDownLatch.countDown();
}
});
t.start();
}
}
});
thread.start();
System.out.println("main is locked");
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + " unlock");
}
}
- CyclicBarrier
适用场景举例:多个线程等待多个线程完成任务一起继续任务
和CountDownLatch类似,可以调用reset()方法重新使用
public class CyclicBarrierExample {
public static void main(String[] args){
CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
for(int i = 0; i < 10;i++) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("i am the "+ Thread.currentThread().getId() + ", I have to wait "+cyclicBarrier.getParties()+" guys then i can go");
try {
cyclicBarrier.await();
System.out.println("i am the "+ Thread.currentThread().getId() + ", I can go");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
}
- Semaphore
适用场景举例:类似于操作系统中的信号量,可以控制对互斥资源的访问线程数。
维护一个信号量,线程纷纷调用acquire()获取信号量,当信号量为0时,其与线程等待,直到其他线程调用release()方法后可以重新获得信号量
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 0;i < 10;i++) {
Thread thread = new Thread(()->{
try {
semaphore.acquire();
System.out.println("Thread id " +Thread.currentThread().getId() + " takes one, left num is " + semaphore.availablePermits());
Thread.currentThread().sleep(1000);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
}
}
- FutureTask
适用场景举例:用作一个任务线程并可以返回结果。
其他线程可以通过.get()操作获得任务执行结果。
public class FutureTaskExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask computeThread = new FutureTask(new Callable() {
@Override
public Integer call() throws Exception {
int res = 0;
for(int i = 0; i < 100;i++) {
Thread.sleep(10);
res += i;
}
return Integer.valueOf(res);
}
});
computeThread.run();
System.out.println("one task is running");
Thread.sleep(1000);
System.out.println("the result is :" + computeThread.get());
}
}
- blockingQueue
适用场景举例:生产者消费者问题
是个接口,提供了一个阻塞队列,当大于capacity值时,队列将不能put;相反capacity等于0时,队列不能take。
public class BlockingQueueExample {
private static ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
private static class producter extends Thread{
@Override
public void run() {
while(true) {
try {
queue.put("product");
System.out.println("product。。。");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class consumer extends Thread {
@Override
public void run() {
while(true) {
try {
Thread.sleep(2000);
String product = queue.take();
System.out.println("consumer。。。");
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
producter producter = new producter();
consumer consumer = new consumer();
producter.start();
Thread.sleep(5000);
consumer.start();
}
}
- ForkJoin
适用方法举例:将一个大任务切分成小任务根据CPU核数并行执行,最后以Future的方式返回结果
ForkJoin任务需要继承RecursiveTask,然后自己写任务切割条件和计算方法,最后由ForkJoinPool负责提交
public class ForkJoinExample extends RecursiveTask<Integer> {
private final int THRESHOLD = 5;
private int first;
private int last;
public ForkJoinExample(int first, int last) {
this.first = first;
this.last = last;
}
@Override
protected Integer compute() {
int result = 0;
if(last - first <= THRESHOLD) {
for(int i = first;i <= last;i++) {
result += i;
}
}else {
int mid = first + (last - first >> 1);
ForkJoinExample left = new ForkJoinExample(first,mid);
ForkJoinExample right = new ForkJoinExample(mid,last);
left.fork();
right.fork();
result = left.join() + right.join();
}
return result;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ForkJoinExample f = new ForkJoinExample(1,10000);
ForkJoinPool forkJoinPool = new ForkJoinPool();
Future res = forkJoinPool.submit(f);
System.out.println(res.get());
}
}