join看起来比较简单,但是join是比较大的,一些人可能用得不是特别好,而且在Api中他的描述也是模棱两可的。
准确来讲应该是:当前线程等待子线程运行结束。具体是什么意思呢?
他有三个重载方法,除了第一个外还有两个是可以做超时限制的(毫秒、纳秒)。
Demo
在开始实战join之前做一个简单的例子(打印0-1000)
借助join的特性去做一些事情,
这两个线程执行的时候势必会去交替(Thread-0和main)
运行结果:
如果让t1输出完在输出main怎么做呢?
调用join()方法后无论怎么执行都是先输出完Thread-0再去输出main。也就是说join()方法则会使得main thread阻塞,等待join返回,一直等到Thread-0线程执行结束后,当前线程才会去执行!
jion()方法必须在start()方法之后
运行结果:
如果除了main线程,那多个线程呢?
main线程不会等到Thread-0执行结束再去等Thread-1执行结束,也就是说对当前线程来说它等Thread-0和Thread-1都结束之后才会去输出打印的文字。
运行结果:
Thread-0和Thread-1是有交替的,他们是并发的一个程序,但是对main线程来说,会等他们结束之后才去执行自己的东西。
join其他Api
设置等待时间
运行结果:
main 线程其实已经结束了,没有退出的原因是还有active的非Daemon线程存在。
案例
服务器相关
有时候我们用到一些嵌入式的HttpServer(jetty),她启动的那部分是个守护线程,这个守护线程的作用是:在主线程退出之后,会把HttpServer挂掉,不让她去占用端口,浪费资源等...
比如说start HttpServer,但是main线程已经终结了,那守护线程也就终结了,也就是说我们写程序的时候会发现,明明已经起来了但是一会就死了。
有一个解决方法是:
Thread.currentThread().join();
。就是说让当前线程join住,直到当前线程死掉,等价于当前线程一直sleep或者做一些其他事情。他的工作就是等自己死掉,
程序会一直是运行状态
。为什么没结束,因为他还在等自己结束 哈哈...
采集各个服务器节点的数据
方式:通过SNMP采集
一个线程负责采集一个服务器,采集完了要保存数据,batch表字段有start、end等也就是只有一条记录插到里面,machines表有字段开始时间,结束时间等。
运行结果:
但是线程才刚刚运行,触发数据采集的动作时,这里就输出结束了。
每个的插入时间肯定是不一样,每一个这时都去插入肯定是有问题的。
解决方式:
运行结果:
这时候呢是等所有数据采集结束之后才是保存记录,虽然都是并发去做的。
- 这就是join的用处,当然现在的Java从5以后的java.util.concurrent包提供给的功能远远比这个要多要丰富,也可以不用join的方式去做。
源码
- join()去调用join(0),传的值为0,也就是等到自然结束。