java util concurrent_java并发包工具(java.util.Concurrent)

一、CyclicBarrier

作用:所有线程准备好才进行,只要一条线程没准备好,都不进行

用法:所有线程准备好以后调用CyclicBarrier的await方法,然后主线程执行CyclicBarrier的countDown方法

实现需求:n个运动员(n个线程),全部准备好了才一起起跑。代码如下

1 packageconcurrent019;2 importjava.io.IOException;3 importjava.util.Random;4 importjava.util.concurrent.BrokenBarrierException;5 importjava.util.concurrent.CyclicBarrier;6 importjava.util.concurrent.ExecutorService;7 importjava.util.concurrent.Executors;8 public classUseCyclicBarrier {9

10 static class Runner implementsRunnable {11 privateCyclicBarrier barrier;12 privateString name;13

14 publicRunner(CyclicBarrier barrier, String name) {15 this.barrier =barrier;16 this.name =name;17 }18 @Override19 public voidrun() {20 try{21 Thread.sleep(1000 * (new Random()).nextInt(5));22 System.out.println(name + " 准备OK.");23 barrier.await();24 } catch(InterruptedException e) {25 e.printStackTrace();26 } catch(BrokenBarrierException e) {27 e.printStackTrace();28 }29 System.out.println(name + " Go!!");30 }31 }32

33 public static void main(String[] args) throwsIOException, InterruptedException {34 CyclicBarrier barrier = new CyclicBarrier(3); //3

35 ExecutorService executor = Executors.newFixedThreadPool(3);36

37 executor.submit(new Thread(new Runner(barrier, "zhangsan")));38 executor.submit(new Thread(new Runner(barrier, "lisi")));39 executor.submit(new Thread(new Runner(barrier, "wangwu")));40

41 executor.shutdown();42 }43

44 }

二、CountDownLacth

作用:监听某些初始化操作,等初始化执行完毕以后,通知主线程继续工作(例如zk的初始化)

用法:将需要别的线程来通知的线程调用CountDownLacth的await方法,其他线程执行了之后,允许这个线程执行的时候,执行CountDownLacth的countDown方法

实现需求:启动3个线程,1线程等待2和3线程执行完毕以后再执行,代码如下:

1 packageconcurrent019;2

3 importjava.util.concurrent.CountDownLatch;4

5 public classUseCountDownLatch {6

7 public static voidmain(String[] args) {8

9 final CountDownLatch countDown = new CountDownLatch(2);10

11 Thread t1 = new Thread(newRunnable() {12 @Override13 public voidrun() {14 try{15 System.out.println("进入线程t1" + "等待其他线程处理完成...");16 countDown.await();17 System.out.println("t1线程继续执行...");18 } catch(InterruptedException e) {19 e.printStackTrace();20 }21 }22 },"t1");23

24 Thread t2 = new Thread(newRunnable() {25 @Override26 public voidrun() {27 try{28 System.out.println("t2线程进行初始化操作...");29 Thread.sleep(3000);30 System.out.println("t2线程初始化完毕,通知t1线程继续...");31 countDown.countDown();32 } catch(InterruptedException e) {33 e.printStackTrace();34 }35 }36 });37 Thread t3 = new Thread(newRunnable() {38 @Override39 public voidrun() {40 try{41 System.out.println("t3线程进行初始化操作...");42 Thread.sleep(4000);43 System.out.println("t3线程初始化完毕,通知t1线程继续...");44 countDown.countDown();45 } catch(InterruptedException e) {46 e.printStackTrace();47 }48 }49 });50

51 t1.start();52 t2.start();53 t3.start();54

55 }56 }

ps:CyclicBarrier和CountDownLacth的区别

CyclicBarrier是所有线程等待一个线程的信号,CountDownLacth是一个线程等待所有线程的信号

三、Callable、Future

Future实现的就是前面讲的Future模式.

实现功能:主线程在执行的过程中,调用了一个或者多个耗时的操作,需要把这个耗时的操作提到另几个线程操作(这几个耗时的操作可以并行执行)

代码实现:

1 packageconcurrent019;2

3 importjava.util.concurrent.Callable;4 importjava.util.concurrent.ExecutorService;5 importjava.util.concurrent.Executors;6 importjava.util.concurrent.FutureTask;7

8 public class UseFuture implements Callable{9 privateString para;10

11 publicUseFuture(String para){12 this.para =para;13 }14

15 /**

16 * 这里是真实的业务逻辑,其执行可能很慢17 */

18 @Override19 public String call() throwsException {20 //模拟执行耗时

21 Thread.sleep(3000);22 String result = this.para + "处理完成";23 returnresult;24 }25

26 //主控制函数

27 public static void main(String[] args) throwsException {28 String queryStr = "query";29 //构造FutureTask,并且传入需要真正进行业务逻辑处理的类,该类一定是实现了Callable接口的类

30 FutureTask future = new FutureTask(newUseFuture(queryStr));31 //创建一个固定线程的线程池且线程数为1,

32 ExecutorService executor = Executors.newFixedThreadPool(1);33 //这里提交任务future,则开启线程执行RealData的call()方法执行

34 executor.submit(future);35 System.out.println("请求完毕");36 try{37 //这里可以做额外的数据操作,也就是主程序执行其他业务逻辑

38 Thread.sleep(2000);39 } catch(Exception e) {40 e.printStackTrace();41 }42 //调用获取数据方法,如果call()方法没有执行完成,则依然会进行等待

43 System.out.println("数据:" + future.get()); //其实这块应该开启线程处理

44 executor.shutdown();45 }46

47 }

四、Semaphore(信号量)

Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有实际的许可证这个对象,Semaphore只是维持了一个可获得许可证的数量。(用于限流)

实现需求:总共有20条线程,但是最多只能放5条线程进来执行

代码实例:

1 packageconcurrent019;2

3 importjava.util.concurrent.ExecutorService;4 importjava.util.concurrent.Executors;5 importjava.util.concurrent.Semaphore;6

7 public classUseSemaphore {8

9 public static voidmain(String[] args) {10 //线程池

11 ExecutorService exec =Executors.newCachedThreadPool();12 //只能5个线程同时访问

13 final Semaphore semp = new Semaphore(5);14 //模拟20个客户端访问

15 for (int index = 0; index < 20; index++) {16 final int NO =index;17 Runnable run = newRunnable() {18 public voidrun() {19 try{20 //获取许可

21 semp.acquire();22 System.out.println("Accessing: " +NO);23 //模拟实际业务逻辑

24 Thread.sleep((long) (Math.random() * 10000));25 //访问完后,释放

26 semp.release();27 } catch(InterruptedException e) {28 }29 }30 };31 exec.execute(run);32 }33

34 try{35 Thread.sleep(10);36 } catch(InterruptedException e) {37 e.printStackTrace();38 }39

40 //System.out.println(semp.getQueueLength());41

42

43

44 //退出线程池

45 exec.shutdown();46 }47

48 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值