java 线程并发包
- 通常为java.util.concurrent 下的包
线程包提供的同步结构主要有三个
- CountDownLatch
- CyclicBarrier
- Semaphore
CountDownLatch
- CountDownLatch 允许一个线程或多个线程等待某些操作完成,一般用于等待事件的促发
- 实例:
/**
* @Author: gsonp
* @Date: 2018/10/10 20:42
*/
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(1);
Thread a=new Thread(new RunnerA(countDownLatch));
a.start();
Thread b=new Thread(new RunnerB(countDownLatch));
b.start();
}
public static class RunnerA implements Runnable{
CountDownLatch countDownLatch;
public RunnerA(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("阻塞 等待B执行完成");
try {
countDownLatch.await();
} catch (InterruptedException e) {
}
System.out.println("B线程执行完成");
}
}
public static class RunnerB implements Runnable{
CountDownLatch countDownLatch;
public RunnerB(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("唤醒A 线程");
countDownLatch.countDown();
}
}
}
执行结果:
阻塞B等待执行完成
唤醒A 线程
B线程执行完成
- CountDownLatch 缺点: CountDownLatch 计数器只有在对象创建的时候被初始化,变为0的时候,就无法再次使用
CyclicBarrier
- CyclicBarier 允许多个线程到达一个屏障,线程阻塞 当最后一个线程到达屏障时,屏障打开,所有线程继续执行。一般用于在多线程计算中,多个线程计算完成,主线程统计结果
- 实例:
public class CyclicBarrierTest {
public static void main(String[] args){
CyclicBarrier cb=new CyclicBarrier(2);
Thread a=new Thread(new RunnerA(cb));
a.start();
Thread b=new Thread(new RunnerB(cb));
b.start();
}
public static class RunnerA implements Runnable{
CyclicBarrier cb;
public RunnerA(CyclicBarrier cb) {
this.cb = cb;
}
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("A执行到达屏障,等待B执行完成");
cb.await();
System.out.println("B执行完成,A继续执行");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static class RunnerB implements Runnable{
CyclicBarrier cb;
public RunnerB(CyclicBarrier cb) {
this.cb = cb;
}
@Override
public void run() {
try {
Thread.sleep(3000);
System.out.println("B执行到达屏障");
cb.await();
System.out.println("B继续执行");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
当CyclicBarrier 屏障打开后,会自动重置,不需要收到调用reset方法
Semaphore
- Semaphore java 版本的信号量,设置permit ,限制对通用资源访问的目的,一般用于对资源访问的控制
- 实例:
/**
* @Author: gsonp
* @Date: 2018/10/11 20:19
*/
public class SemaphoreTest {
public static void main(String[] args){
Semaphore sp=new Semaphore(1);
Thread a=new Thread(new RunnerA(sp));
a.start();
Thread b=new Thread(new RunnerB(sp));
b.start();
}
public static class RunnerA implements Runnable{
Semaphore sp;
public RunnerA(Semaphore sp) {
this.sp = sp;
}
@Override
public void run() {
try {
System.out.println("A执行获取permit");
sp.acquire();
Thread.sleep(4000);
sp.release();
System.out.println("A执行完成,释放permit");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static class RunnerB implements Runnable{
Semaphore sp;
public RunnerB(Semaphore sp) {
this.sp = sp;
}
@Override
public void run() {
try {
System.out.println("B执行等待获取permit");
sp.acquire();
System.out.println("B执行完毕是否permit");
sp.release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Semaphore 一般用于对资源的访问做限制