• 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,也就是等到自然结束。

results matching ""

    No results matching ""