并发工具类
- CountDownLatch:使当前线程必须等待其他线程执行完再执行
CountDownLatch c=new CountDownLatch(2);
c,await();//主线程调用该方法进行阻塞自己,表示等待其他线程执行完
c.countDown();//副线程每调用一次该方法表示计数+1,副线程必须调用两次该方法,才能唤醒主线程;多个副线程可以分别调用countDown()方法,只要调用满2次就唤醒主线程
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
static CountDownLatch c = new CountDownLatch(2);
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
System.out.println("线程1开始执行!");
Thread.sleep(3000);
System.out.println("线程1结束执行!");
c.countDown();
} catch (InterruptedException e) {
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
System.out.println("线程2开始执行!");
Thread.sleep(5000);
System.out.println("线程2结束执行!");
c.countDown();
} catch (InterruptedException e) {
}
}
});
t1.start();
t2.start();
try {
System.out.println("开始等待线程1、2结束");
c.await();
System.out.println("线程1、2结束");
} catch (InterruptedException e) {
}
}
}
- CyclicBarrier:当一组线程到达屏障时每个线程都会被阻塞,直到最后一个线程到达屏障,屏障才会开门让这组的每个线程执行下去
CyclicBarrier c=new CyclicBarrier(3);//3表示有三个线程到达屏障
c.await();//最后一个线程调用了该方法,则3个线程同时被唤醒继续执行下去
注意:CountDownLatch和CyclicBarrier的区别是,CountDownLatch是一个线程等待其他所有线程,CyclicBarrier是所有线程等待一个线程;而且CountDownLatch的计数器只能使用一次,而CountDownLatch得计数器使用后还可以reset()进行重置
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
static CountDownLatch c = new CountDownLatch(2);
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
System.out.println("线程1开始执行!");
Thread.sleep(3000);
System.out.println("线程1结束执行!");
c.countDown();
} catch (InterruptedException e) {
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
System.out.println("线程2开始执行!");
Thread.sleep(5000);
System.out.println("线程2结束执行!");
c.countDown();
} catch (InterruptedException e) {
}
}
});
t1.start();
t2.start();
try {
System.out.println("开始等待线程1、2结束");
c.await();
System.out.println("线程1、2结束");
} catch (InterruptedException e) {
}
}
}
- Exchanger:两个线程间交换数据
两个线程通过exchange()交换数据,第一个线程调用exchange()后会等待第二个线程也调用exchange(),然后它们互换携带的数据,否则第一个线程会一直等待第二个线程执行exchange()
package chapter3.exchanger;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* @author czd
*/
public class ExchangerTest2 {
public static void main(String] args) {
final Exchanger<Object> exchanger = new Exchanger<>();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始启动....");
try {
Object object = new Object();
Object obj = exchanger.exchange(object);
System.out.println(Thread.currentThread().getName() + " Thread-A send Object: " + object);
System.out.println(Thread.currentThread().getName() + " Thread-A get Object: " + obj);
}catch (InterruptedException e){
e.printStackTrace();
}
}
},"Thread-A").start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始启动....");
try {
TimeUnit.SECONDS.sleep(5);
Object object = new Object();
Object obj = exchanger.exchange(object);
System.out.println(Thread.currentThread().getName() + " Thread-B send Object: " + object);
System.out.println(Thread.currentThread().getName() + " Thread-B get Object: " + obj);
}catch (Exception e){
e.printStackTrace();
}
}
},"Thread-B").start();
}
}
结果:

---------------------------------------------------------------------------------------------------
文章定期同步更新于公众号【小大白日志】,欢迎关注公众号:


浙公网安备 33010602011771号