Java中的并发工具类

Java并发工具类

1、Java常见的并发工具类

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
  • Exchanger

CountDownLatch
用过Thread的join()都知道,join让主线程等待“子线程”,结束之后,才能继续运行,Jdk1.5之后提供了CountDownLatch。它提供了比Join更丰富的功能,一种共享锁;

常见api

  • 构造函数接收一个int值作为计数器,想n个线程等n个点就传如N
 public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }
  • countDown();释放共享锁
   public void countDown() {
        sync.releaseShared(1);
    }

应用示例代码:

public class CountDownLatchTest {

    static CountDownLatch  countDownLatch = new CountDownLatch(2);

    public static void main(String[] args) {

        try {
            new Thread(()->{
                try {
                    System.out.println("1");
                    countDownLatch.countDown();
                    Thread.sleep(3000);
                    System.out.println("2");
                    countDownLatch.countDown();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
            countDownLatch.await();
            System.out.println("3");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

CyclicBarrier

表示意思理解为可循环使用的屏障,作用是让一组线程在到达一个屏障时被阻塞,等到最后一个线程到达屏障点,才会让被拦截的线程继续运行。

  • 构造函数,parties指的是屏障拦截的线程数
 public CyclicBarrier(int parties) {
        this(parties, null);
    }
  • await()调用该方法时表示线程已到达屏障,随即阻塞

应用示例:

public class CyclicBarrierTest {

    static CyclicBarrier c = new CyclicBarrier(2);

    public static void main(String[] args) {
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(5);
                c.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("1");
        }).start();
        try {
            c.await();
            System.out.println("2");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

高级构造函数 CyclicBarrier(int,Runnable)优先执行

public class CyclicBarrierTest2 {

    static CyclicBarrier c =new CyclicBarrier(2,new A());

    public static void main(String[] args) {
        new Thread(
                ()->{
                    try {
                        TimeUnit.SECONDS.sleep(5);
                        c.await();
                        System.out.println("1");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        ).start();

        try {
            c.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println("2");
    }


    private static class A implements Runnable{
        @Override
        public void run() {
            System.out.println("3");
        }
    }
}

3、两者的区别

  • CountDownLatch只能用一次,CyclicBarrier可以reset(),且适合处理复杂逻辑的业务;
  • CyclicBarrier还有getNumberWaiting获取当前阻塞的线程数量,isBroken()了解阻塞线程是否中断;

public class CyclicBarrierTest3 {

    static CyclicBarrier c =new CyclicBarrier(2);

    public static void main(String[] args) {

        Thread t = new Thread(()->{
            try {
                c.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        });

        t.start();
//     t.interrupt();
        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println(c.getNumberWaiting());
            c.await();
//            System.out.println(c.getNumberWaiting());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Semaphore

  • 用来控制同时访问资源的线程数量,通过协调保证合理的使用公共资源;
  • 其他常见api
    int availablePermits() 返回此信号量中当前可用的许可证数
    int getQueueLength() 正在等待获取许可证的线程数
    boolean hasQueuedThreads() 是否有线程正在等待获取许可证
    void reducePermits() 减少许可证
    Collection getQueuedThreads() 返回所有等待获取许可证的线程集

    应用示例:
public class SemaphoreTest {

    private static final int THREAD_COUNT = 30;

    private  static ExecutorService pool = Executors.newFixedThreadPool(THREAD_COUNT);

    private  static Semaphore s = new Semaphore(10);

    public static void main(String[] args) {
        for (int i = 0; i <THREAD_COUNT ; i++) {
            pool.execute(()->{
                try {
                    s.acquire();
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(Thread.currentThread().getName()+"线程释放资源");
                    s.release();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        pool.shutdown();
    }

}

Exchanger

线程之间的数据交换,提供一个同步点,两个线程可以交换彼此数据,通过exchange()交换数据,当两个线程执行到exchange()方法,可以将本线程的数据传递给对方。

应用场景:
1、遗传算法
2、校对工作

示例代码:

public class ExchangerTest {

    static Exchanger<String> exchanger = new Exchanger();

    public static void main(String[] args) {

        ExecutorService service = Executors.newFixedThreadPool(2);

        service.execute(()->{
            String A ="F";
            try {
                System.out.println("交换后结果:"+exchanger.exchange(A));  ;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        service.execute(()->{
            try {
                String B ="B";
                String A = exchanger.exchange("C");

                System.out.println("是否一致"+A.equals(B)+"A::"+A+"B::"+B);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        service.shutdown();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值