J.U.C知识点梳理
java.util.concurrent : 提供了并发编程的解决方案
1、CAS 是java.util.concurrent.atomic包的基础
2、AQS是java.util.concurrent.locks包以及一些常用类,比如:Semophore ,ReentrantLock等类的基础
J.U.C包的分类
1、线程执行器executor
2、锁locks
3、原子变量类atomic
4、并发工具类 tools
5、并发集合collections

并发工具类
1、闭锁 CountDownLatch
2、栅栏 CyclicBarrier
3、信号量Semaphore
4、交换器 Exchanger

public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
new CountDownLatchDemo().go();
}
private void go() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(3);
// 依次创建3个线程,并启动
new Thread(new Task(countDownLatch), "Thread1").start();
Thread.sleep(1000);
new Thread(new Task(countDownLatch), "Thread2").start();
Thread.sleep(1000);
new Thread(new Task(countDownLatch), "Thread3").start();
countDownLatch.await();
System.out.println("所有线程已到达,主线程开始执行" + System.currentTimeMillis());
}
class Task implements Runnable {
private CountDownLatch countDownLatch;
public Task(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName() + "已经到达" + System.currentTimeMillis());
countDownLatch.countDown();
}
}
}

public class CyclicBarrierDemo {
public static void main(String[] args) throws InterruptedException {
new CyclicBarrierDemo().go();
}
private void go() throws InterruptedException {
// 初始化栅栏的参与者数为3
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
// 依次创建3个线程,并启动
new Thread(new Task(cyclicBarrier), "Thread1").start();
Thread.sleep(1000);
new Thread(new Task(cyclicBarrier), "Thread2").start();
Thread.sleep(1000);
new Thread(new Task(cyclicBarrier), "Thread3").start();
Thread.sleep(1000);
System.out.println("main");
}
class Task implements Runnable {
private CyclicBarrier cyclicBarrier;
public Task(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName() + "已经到达" + System.currentTimeMillis());
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "开始处理" + System.currentTimeMillis());
}
}
}

public class SemaphoreDemo {
public static void main(String[] args) {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool();
// 只能5个线程同时访问
final Semaphore semp = new Semaphore(5);
// 模拟20个客户端访问
for (int index = 0; index < 20; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
semp.acquire();
System.out.println("Accessing: " + NO);
Thread.sleep((long) (Math.random() * 10000));
// 访问完后,释放
semp.release();
} catch (InterruptedException e) {
}
}
};
exec.execute(run);
}
// 退出线程池
exec.shutdown();
}
}

public class ExchangerDemo {
private static Exchanger<String> exchanger = new Exchanger();
public static void main(String[] args) {
//代表男生和女生
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(() -> {
try {
//男生对女生说的话
String girl = exchanger.exchange("我其实暗恋你很久了......");
System.out.println("女生说:" + girl);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
service.execute(() -> {
try {
System.out.println("女生慢慢的从教室里走出来......");
TimeUnit.SECONDS.sleep(3);
//男生对女生说的话
String boy = exchanger.exchange("我很喜欢你......");
System.out.println("男生说:" + boy);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
service.shutdown();
} }

主要用于生产者-消费者模式,在多线程场景时生产者线程在队列尾部添加元素,而消费者线程则在队列头部消费元素,通过这种方式能够达到将任务的生产和消费进行隔离的目的。
注意:BlockingQueue的加入方法,offer(),add(),put()


浙公网安备 33010602011771号