通过Thread.join()和CountDownLatch来实现进程同步
来源:互联网 发布:淘宝助理上传宝贝教程 编辑:程序博客网 时间:2024/05/22 15:38
1.Thread.join()
如果在一个进程,如main中调用另一个thread的join()函数会导致main函数阻塞,直至thread执行完毕。
public class JoinTest {public static void main(String[] args) {System.out.println("main starts.");Thread thread = new Thread(new Runnable() {public void run() {for(int i = 0;i < 5;i++){try {System.out.println("thread" + i + " starts.");Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}});thread.start();try {thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("main ends.");}}
输出结果为:
main starts.thread0 starts.thread1 starts.thread2 starts.thread3 starts.thread4 starts.main ends.
从输出结果来看,main线程打印了main starts,执行到thread.join()被阻塞了,此时子线程开始打印log,且打印间隔为500ms,当子线程执行完毕后,main线程打印输出main ends。
如果我们将thread.join()改成thread.join(1500),那么输出结果如下:
main starts.thread0 starts.thread1 starts.thread2 starts.main ends.thread3 starts.thread4 starts.
这里采用的是join的一个重载方法,join(long millis),表示等到线程thread执行完毕或者阻塞millis时间后才能允许调用这个函数的线程继续执行下去。从上述输出中我们可以看出main线程并没有等待thread执行完毕,而是等待了1500ms就继续执行了。
其实,这里还可以用这种方法来实现main线程等待thread线程:
//try {//thread.join();//} catch (InterruptedException e) {//e.printStackTrace();//}while(thread.isAlive()){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}
判断thread是否处于alive状态,如果是那么main线程休眠100ms,如果thread结束了,main再继续执行。
2.CountDownLatch
CountDownLatch中维护了一个计数器,初始化时接受一个整型值作为计数器初始值,其中包括两个函数await和countDown,当在某个函数中调用await时,该线程被阻塞,没调用一次countDown计数器值减一,只有当计数器的值为0的时候刚才被阻塞的线程才能继续向下执行。
public class CountDownLatchTest {public static void main(String[] args) throws InterruptedException {final CountDownLatch startCdt = new CountDownLatch(5);final CountDownLatch endCdt = new CountDownLatch(5);for(int i = 0; i < 5; i++){new Thread(new Runnable(){public void run() {System.out.println(Thread.currentThread().getName() + "starts.");try {startCdt.countDown();startCdt.await();//创建的5个线程都在等startCdt的count=0才继续往下执行} catch (InterruptedException e) {e.printStackTrace();}finally{endCdt.countDown();//每个线程执行完后都将count值减1System.out.println(Thread.currentThread().getName() + " ends.");}}}).start();}endCdt.await();//main线程当endCdt的值为0时才继续执行,也就是等上边创建的5个线程执行完毕后才继续执行System.out.println("all threads end.");}
执行结果如下:
Thread-1starts.Thread-3starts.Thread-4starts.Thread-2starts.Thread-0starts.Thread-0 ends.Thread-1 ends.Thread-3 ends.Thread-4 ends.Thread-2 ends.all threads end.尽管每个子线程创建后立刻执行,但是当他们在运行到startCdt.await()时都被阻塞了,只有startCdt的计数器的值减为0时才继续向下执行;同理main线程在执行到endCdt.await()时阻塞,只有当其计数器减为0时才继续执行。如果没有endCdt.await(),那么执行结果如下:
Thread-1starts.Thread-4starts.Thread-0starts.all threads end.Thread-2starts.Thread-3starts.Thread-3 ends.Thread-1 ends.Thread-4 ends.Thread-0 ends.Thread-2 ends.
- 通过Thread.join()和CountDownLatch来实现进程同步
- 采用Thread.join()或CountDownLatch来实现线程间同步
- 【Java并发】(二) 线程同步之Thread.join()、CountDownLatch、CyclicBarrier
- 通过CountDownLatch实现websocket同步返回
- 进程间同步(Process Synchronization)-2 通过semaphore方式来实现进程间同步的例子
- 多线程CountDownLatch和Join
- 通过使用Thread.join()函数使异步线程变得同步
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- CountDownLatch和join两种方式实现多线程并行处理
- Java并发之 CAS + Thread.join / CountDownLatch 方式实现线程安全
- 利用Thread类的join方法实现线程同步
- 通过互斥量和读写锁来实现进程间通信
- 对比:通过实现Runnable接口和继承thread类来生成多线程
- Thread.Join()和Thread.Sleep()
- Thread.Join()和Thread.Sleep()
- thread::join和thread::detach
- Java中CountDownLatch、CyclicBarrier、Thread.join方法基本应用
- 字符串使用总结
- Struts2系列(一) Struts2生成动态验证码代码分析
- 一些特殊容器:string,bitset,vector<bool>,空容器
- SAP ABAP程序效率优化 Perfomance Tune
- 开源中国android客户端学习 第一天
- 通过Thread.join()和CountDownLatch来实现进程同步
- C#实现万年历
- CentOS-6.3安装配置SVN
- Eclipse一些使用快捷方式
- Nutch 插件系统浅析
- warning LNK4089: all references to "USER32.dll" /"ole32.dll" discarded by /OPT:REF
- 日积月累:Android项目打第三方jar包
- S 7 - Status bar overlaps the view
- 在现在的CMP上的共享缓存是否对于目前的多线程应用有影响?