博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CyclicBarrier、CountDownLatch、Callable、FutureTask、thread.join() 、wait()、notify()、Condition...
阅读量:6921 次
发布时间:2019-06-27

本文共 10168 字,大约阅读时间需要 33 分钟。

CyclicBarrier使用:

import java.util.Random;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * 三个运动员各自准备,等到三个人都准备好后,再一起跑
@see 1:先创建一个公共 CyclicBarrier 对象,设置 同时等待 的线程数,CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
2:这些线程同时开始自己做准备,自身准备完毕后,需要等待别人准备完毕,这时调用 cyclicBarrier.await(); 即可开始等待别人;
3:当指定的 同时等待 的线程数都调用了 cyclicBarrier.await();时,意味着这些线程都准备完毕好,然后这些线程才 同时继续执行。
* */public class TestCyclicBarrier { public static void main(String[] args) { int runner = 3; final CyclicBarrier cycliBarrier = new CyclicBarrier(runner); final Random random = new Random(); for (char runnerName = 'A'; runnerName <= 'C'; runnerName++) { final String rName = String.valueOf(runnerName); new Thread(new Runnable(){ @Override public void run() { long prepareTime = random.nextInt(10000)+100; System.out.println(rName + " is preparing for time: " + prepareTime); try { Thread.sleep(prepareTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(rName + " is prepared, waiting for others"); try { cycliBarrier.await(); // 当前运动员准备完毕,等待别人准备好 } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println(rName + " starts running"); // 所有运动员都准备好了,一起开始跑 } }).start(); } }}

输出:

CountDownLatch例子

import java.util.concurrent.CountDownLatch;/** * 四个线程 A B C D,其中 D 要等到 A B C 全执行完毕后才执行,而且 A B C 是同步运行的@see 1:创建一个计数器,设置初始值,CountdownLatch countDownLatch = new CountDownLatch(2);
2:在 等待线程 里调用 countDownLatch.await() 方法,进入等待状态,直到计数值变成 0;
3:在 其他线程 里,调用 countDownLatch.countDown() 方法,该方法会将计数值减小 1;
4:当 其他线程 的 countDown() 方法把计数值变成 0 时,等待线程 里的 countDownLatch.await() 立即退出,继续执行下面的代码。
* */public class TestCountDownLatch { public static void main(String[] args) { int workerNum = 3; final CountDownLatch countDownlatch = new CountDownLatch(workerNum); new Thread(new Runnable(){ @Override public void run() { System.out.println("D is waiting for other three threads"); try { countDownlatch.await(); System.out.println("D is start work"); Thread.sleep(100); System.out.println("D finsh Work"); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); for (char threadName = 'A'; threadName <= 'C'; threadName++) { final String tName = String.valueOf(threadName); new Thread(new Runnable(){ @Override public void run() { System.out.println(tName + " is working"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(tName + " finished"); countDownlatch.countDown(); } }).start(); } }}

输出:

FutureTask、Callable例子

import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;/** * 我们想让子线程去计算从 1 加到 100,并把算出的结果返回到主线程
* @see * 如何把子线程的结果回传回来呢?在 Java 里,有一个类是配合 Callable 使用的:FutureTask,不过注意,它获取结果的 get 方法会阻塞主线程。 * */public class TestCallableAndFutureTask { public static void main(String[] args) { Callable
callAble = new Callable
() { @Override public Integer call() throws Exception { System.out.println("Task starts"); Thread.sleep(100); int result = 0; for (int i = 0; i <= 100; i++) { result += i; } System.out.println("Task finished and return result"); return result; } }; FutureTask
futureTask = new FutureTask
(callAble); new Thread(futureTask).start(); try { System.out.println("Before futureTask.get()"); System.out.println("Result: " + futureTask.get()); System.out.println("After futureTask.get()"); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}

 输出:

 thread.join()  例子

/** * 实现效果:线程B在线程A完成之后再执行 * thread.join()  * */public class TestThreadJoin {    public static void main(String[] args) {        demo1();    }        private static void demo1() {        final Thread A = new Thread(new Runnable(){            @Override            public void run() {                PrintNumber("A");            }                    }) ;                Thread B = new Thread(new Runnable(){            @Override            public void run() {                System.out.println("B 开始等待A");                try {                    A.join();                } catch (InterruptedException e) {                    e.printStackTrace();                }                PrintNumber("B");            }                    }) ;        A.start();        B.start();    }        private static void PrintNumber(String ThreadName) {        int i = 0;        while (i++ < 3) {            try {                Thread.sleep(100);            } catch(InterruptedException e) {                e.printStackTrace();            }            System.out.println(ThreadName + " print: " + i);        }    }}

输出:

wait()、notify() 例子:

public class TestWaitAndnotify {    public static void main(String[] args) {        demo2();    }        public static void demo2 () {        final Object lock = new Object();        Thread A = new Thread(new Runnable(){            @Override            public void run() {                System.out.println("INFO: A 等待锁 ");                synchronized (lock) {                    System.out.println("INFO: A 得到了锁 lock");                    System.out.println("A1");                    try {                        System.out.println("INFO: A 准备进入等待状态,放弃锁 lock 的控制权 ");                        lock.wait();//挂起线程A 放弃锁 lock 的控制权                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println("INFO: 有人唤醒了 A, A 重新获得锁 lock");                    System.out.println("A2");                    System.out.println("A3");                }            }        });                Thread B = new Thread(new Runnable() {            @Override            public void run() {                 System.out.println("INFO: B 等待锁 ");                synchronized (lock) {                    System.out.println("INFO: B 得到了锁 lock");                    System.out.println("B1");                    System.out.println("B2");                    System.out.println("B3");                    System.out.println("INFO: B 打印完毕,调用 notify 方法 ");                    lock.notify(); // notify()方法唤醒正在等待lock锁的线程A                    System.out.println("线程 B do notify method 完毕");                }            }        });                A.start();        B.start();    } }

输出:

 Condition 例子(生产消费):

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class TestCondition {        public static void main(String[] args) {          final BoundedBuffer b = new BoundedBuffer();                  new Thread(new Runnable() {    // 写线程            public void run() {                  int i = 1;                  while (true) {                      try {                          b.put(i++);                      } catch (InterruptedException e) {                          e.printStackTrace();                      }                  }              }        }).start();                 new Thread(new Runnable() {  // 读线程            public void run() {                  while (true) {                      try {                          b.take();                      } catch (InterruptedException e) {                          e.printStackTrace();                      }                  }              }          }).start();      }}class BoundedBuffer{    final Lock lock = new ReentrantLock();  // 锁对象      final Condition notFull = lock.newCondition();  // 写线程条件     final Condition notEmpty = lock.newCondition();  // 读线程条件        final Integer[] items = new Integer[10]; // 缓存队列      int putptr;  // 写索引    int takeptr; // 读索引    int count;   // 队列中存在的数据个数        public void put(Integer x) throws InterruptedException {        lock.lock();        try {            while(count == items.length) {  // 如果队列满了                  notFull.await();  // 阻塞写线程            }            items[putptr] = x;  // 赋值             System.out.println("写入:" + x);            if(++putptr == items.length) { // 如果写索引写到队列的最后一个位置了,那么置为0                 putptr = 0;            }            ++count; // 个数++              notEmpty.signal(); // 唤醒读线程          } finally {            lock.unlock();        }    }        public Integer take() throws InterruptedException {        lock.lock();        try {            while(count == 0) { // 如果队列为空                  notEmpty.await(); // 阻塞读线程            }            Integer x = items[takeptr]; // 取值              System.out.println("读取:" + x);            if(++takeptr == items.length) { // 如果读索引读到队列的最后一个位置了,那么置为0                  takeptr = 0;            }            --count; // 个数--              notFull.signal();            return x;        } finally {            lock.unlock();        }    }}

输出:

.......

 

转载于:https://www.cnblogs.com/myseries/p/11084767.html

你可能感兴趣的文章
通过Intel XDK编写跨平台app(二)
查看>>
cache和buffer介绍
查看>>
论刚入门的菜鸟如何学网络安全,如何学习***测试,网络安全菜鸟的学习之旅...
查看>>
feignclient的拦截
查看>>
聊聊flink的log.file配置
查看>>
伪造的ARP应答报文,阻碍对方通信
查看>>
iOS BLE4.0开发--工作中遇到的一些坑
查看>>
执行Shell脚本的4种方法
查看>>
部署QtQuick应用程序到安卓设备上时,AVD突然检测不到目标设备
查看>>
Linux笔记(shell基础,历史命令,命令补全/别名,通配符,输出重定向)
查看>>
Yii2---composer方法安装(Mac+MAMP)
查看>>
运维文章
查看>>
转-深入探讨Ruby与Python语法比较
查看>>
linux redhat6.5中 搭建NFS服务
查看>>
JMeter接口压力测试课程入门到高级实战(目录)
查看>>
extjs与struts开发的项目
查看>>
Linux20180423五周第四次课(4月23日)
查看>>
eclipse项目中,dubbo.xml不能识别schema报错
查看>>
MySQL中concat函数(连接字符串)
查看>>
[版本控制]原来Git分支都是这么用的
查看>>