线程通信
问题清单:
- 如何让两个线程依次执行?
- 如何让两个线程按照指定方式有序交叉运行?
- 四个线程 A B C D,其中 D 要等到 A B C 全执行完毕后才执行,而且 A B C 是同步运行的。
- 三个线程各自准备,等到三个线程都准备好后,再一起执行某个任务。
- 子线程完成某件任务后,把得到的结果回传给主线程。
两个线程依次执行?
假设有两个线程,一个是线程 A,另一个是线程 B,两个线程分别依次打印 1-3 三个数字:
这个可说的不多,就是在B线程中加入A.join();
代码如下:
如何让两个线程按照指定方式有序交叉运行呢?
假如, A 在打印完 1 后,再让 B 打印 1, 2, 3,最后再回到 A 继续打印 2, 3。可以利用 object.wait() 和 object.notify() 两个方法来实现。
思路:两个线程使用同一把锁,A线程打印完1后调用wait()方法释放锁(此时的B没有锁,并没执行打印的动作),A释放了锁之后B获得了锁,开始执行打印1 2 3的动作,执行完毕的B线程调用notify()唤醒在wait的A线程,A继续打印2 3。
代码如下:
四个线程 A B C D,其中 D 要等到 A B C 全执行完毕后才执行,而且 A B C 是同步运行的
要求是同时运行,所以不能使用join(),因为ABC会顺序执行。换言之,就是ABC执行完成后通知D,然后D再执行他的任务。这种情况,我们可以利用 countdownlatch 来实现这类通信方式。CountDownLatch 适用于一个线程去等待多个线程的情况。
先解释一下CountdownLatch,CountdownLatch是一个计数器,设置一下数量(本题设置成3就好),计数器为0时线程开始执行任务。
思路:在D线程中调用countDownLatch.await()进入等待状态,直到计数器为0。在ABC线程中,执行完各自的任务后调用countDownLatchcountDown()方法,这样计数器会 -1。一旦countDownLatch计数器变成0,countDownLatch.await()立即退出,继续执行代码。
代码如下:
三个线程各自准备,等到三个线程都准备好后,再一起执行某个任务
线程 A B C 各自开始准备,直到三者都准备完毕,然后再同时运行。实现一种 线程之间互相等待 的效果。
相互等待的效果,可以使用CyclicBarrier(栅栏) 数据结构。
思路: 创建一个公共的CyclicBarrier,然后设置同时等待的线程数(ABC三个线程,设置成3即可)。然后在ABC三个线程中,分别准备完毕后调用CyclicBarrier.await()方法,开始等待其他线程。ABC三个线程都调用了await()方法后,再分别执行后面的代码。
代码如下:
子线程完成某件任务后,把得到的结果回传给主线程。
创建一个线程,我们一般会把 Runnable 对象传给 Thread 去执行,调用start之后执行的是run()方法,而run()方法是没有返回值的,也就没法把结果返回。
如果想接收到返回值,可以使用类似于Runnable的接口:Callable。
Callable接口的定义如下:
最明显的区别就是返回结果是范型 V 。
返回的结果要使用另一个类来接受:FutureTask。它是配合Callable使用的。值得注意的一点,FutureTask它获取结果的 get 方法会阻塞主线程。
举例:子线程去计算从 1 加到 100,并把算出的结果返回到主线程。
代码如下:
执行结果如下:
从执行结果可以看出:
主线程调用 futureTask.get() 方法时阻塞主线程;
然后 Callable 内部开始执行,并返回运算结果;
此时 futureTask.get() 得到结果,主线程恢复运行。
这里我们可以学到:
通过 FutureTask 和 Callable 可以直接在主线程获得子线程的运算结果,只不过需要阻塞主线程。
如果不希望阻塞主线程,可以考虑利用 ExecutorService,把 FutureTask 放到线程池去管理执行。
文章最后发布于: 2018-02-28 16:21:53
相关阅读
进程和线程的区别 进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
https://github.com/jae-jae/camtdhttps://aria2.github.io/切换到解压目录D:\Tools\aria2-1.34.0-win-64bit中,打开cmd输入命令
PHP 从设计之初到流行起来都没有出现明显需要用多线程才能解决的需求。某些需要用到多线程的地方也有相应的解决方案和替代方案。
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅
(代码来源网络共享) 这几个工具类其实说白了就是为了能够更好控制线程之间的通讯问题~ CountDownLatch 是一个同步的辅助类,允许
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。socket本质是编程接口(API),对TCP/IP的封