微信搜索:小大白日志

并发工具类

  • 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();
    }
}

结果:

 

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

 

 

posted @ 2021-03-27 08:23  明天喝可乐  阅读(64)  评论(0)    收藏  举报