欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 异步回调之Join

异步回调之Join

2025/2/23 1:58:51 来源:https://blog.csdn.net/m0_68082638/article/details/143455369  浏览:    关键词:异步回调之Join

join:异步阻塞之闷葫芦

阻塞模式实现泡茶实例首先从基础的多线程join合并实验入手.join操作的原理是阻塞当前线程,直到待合并的目标线程执行完成.

线程的合并流程

Java中线程的合并流程是:假设线程A调用线程B的join()方法去合并B线程,那么线程A进入阻塞状态,直到线程B执行完成.

泡茶例子中,主线程通过分别调用烧水线程和清洗线程的join()方法,等待烧水线程和清洗线程完成,然后主线程执行泡茶操作.流程参考图如下.

通过join()实现异步泡茶喝

通过join实现一个异步阻塞版本,参考如下.

public class JoinDemo {public static final int SLEEP_GAP = 500;public static String getCurrentThreadName() {return Thread.currentThread().getName();}static class HotWaterThread extends Thread {public HotWaterThread() {super("烧水--Thread");}@Overridepublic void run() {try {System.out.println("洗好水壶");System.out.println("灌上凉水");System.out.println("放在火上");Thread.sleep(SLEEP_GAP);System.out.println("水开了");} catch (InterruptedException e) {System.out.println("烧水失败");}System.out.println("运行结束");}}static class WashThread extends Thread {public WashThread() {super("清洗--Thread");}@Overridepublic void run() {try {System.out.println("洗茶壶");System.out.println("洗茶杯");System.out.println("拿茶叶");Thread.sleep(SLEEP_GAP);System.out.println("洗完了");} catch (InterruptedException e) {System.out.println("洗茶壶茶杯失败");}System.out.println("运行结束");}}public static void main(String[] args) {WashThread washThread = new WashThread();HotWaterThread hotWaterThread = new HotWaterThread();washThread.start();hotWaterThread.start();try {washThread.join();hotWaterThread.join();Thread.currentThread().setName("主线程");System.out.println("泡茶喝");} catch (InterruptedException e) {e.printStackTrace();}System.out.println(getCurrentThreadName() + "运行结束");}
}

程序中有三个线程:主线程main 烧水线程HotWaterThread 清洗线程WashThread,主线程调用了这两个线程的join方法进行合并.

Join()方法详解

join方法应用场景如下:

A线程调用B线程的join方法,等待B线程执行完成,在B线程没有完成之前,A线程阻塞.

Join()方法有三个重载版本:

    /*** Waits for this thread to die.** <p> An invocation of this method behaves in exactly the same* way as the invocation** <blockquote>* {@linkplain #join(long) join}{@code (0)}* </blockquote>** @throws  InterruptedException*          if any thread has interrupted the current thread. The*          <i>interrupted status</i> of the current thread is*          cleared when this exception is thrown.*/public final void join() throws InterruptedException {join(0);}

A线程等待B线程执行结束后,A线程重新开始执行. 

    /*** Counts the number of stack frames in this thread. The thread must* be suspended.** @return     the number of stack frames in this thread.* @exception  IllegalThreadStateException  if this thread is not*             suspended.* @deprecated The definition of this call depends on {@link #suspend},*             which is deprecated.  Further, the results of this call*             were never well-defined.*/@Deprecatedpublic native int countStackFrames();/*** Waits at most {@code millis} milliseconds for this thread to* die. A timeout of {@code 0} means to wait forever.** <p> This implementation uses a loop of {@code this.wait} calls* conditioned on {@code this.isAlive}. As a thread terminates the* {@code this.notifyAll} method is invoked. It is recommended that* applications not use {@code wait}, {@code notify}, or* {@code notifyAll} on {@code Thread} instances.** @param  millis*         the time to wait in milliseconds** @throws  IllegalArgumentException*          if the value of {@code millis} is negative** @throws  InterruptedException*          if any thread has interrupted the current thread. The*          <i>interrupted status</i> of the current thread is*          cleared when this exception is thrown.*/public final synchronized void join(long millis)throws InterruptedException {long base = System.currentTimeMillis();long now = 0;if (millis < 0) {throw new IllegalArgumentException("timeout value is negative");}if (millis == 0) {while (isAlive()) {wait(0);}} else {while (isAlive()) {long delay = millis - now;if (delay <= 0) {break;}wait(delay);now = System.currentTimeMillis() - base;}}}

A线程等待B线程执行一段时间,最长时间为millis 毫秒,超过后就会A线程重新执行.

    /*** Waits at most {@code millis} milliseconds plus* {@code nanos} nanoseconds for this thread to die.** <p> This implementation uses a loop of {@code this.wait} calls* conditioned on {@code this.isAlive}. As a thread terminates the* {@code this.notifyAll} method is invoked. It is recommended that* applications not use {@code wait}, {@code notify}, or* {@code notifyAll} on {@code Thread} instances.** @param  millis*         the time to wait in milliseconds** @param  nanos*         {@code 0-999999} additional nanoseconds to wait** @throws  IllegalArgumentException*          if the value of {@code millis} is negative, or the value*          of {@code nanos} is not in the range {@code 0-999999}** @throws  InterruptedException*          if any thread has interrupted the current thread. The*          <i>interrupted status</i> of the current thread is*          cleared when this exception is thrown.*/public final synchronized void join(long millis, int nanos)throws InterruptedException {if (millis < 0) {throw new IllegalArgumentException("timeout value is negative");}if (nanos < 0 || nanos > 999999) {throw new IllegalArgumentException("nanosecond timeout value out of range");}if (nanos >= 500000 || (nanos != 0 && millis == 0)) {millis++;}join(millis);}

A线程等待B线程执行一段时间,最长时间为millis 毫秒加nanos纳秒,超过后就会A线程重新执行.

容易混淆的几点.

join()是实例方法,不是静态方法.

调用join方法时,不是thread所指向的目标线程阻塞,而是当前线程被阻塞.

只有等待的thread执行完成或者超时,当前线程才能启动执行.

总结下,join方法通过上面的源码可以看出,是不断通过检查线程是否存存活,来进行阻塞.直到被唤醒才会解除阻塞.而且join方法不能拿到返回结果,缺少很多的灵活性.所以join更多的停留在Demo演示上.

坚持读书久了,会发现自己变得温文尔雅.技术坚持久了,理解也会越来越深.

多给自己一点坚持.云淡风轻 温文尔雅是由内而外的.

如果大家喜欢我的分析的话,可以关注下我的微信公众号

心有九月星辰

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词