2023年7月22日发(作者:)
()详解⼀、使⽤⽅式。join是Thread类的⼀个⽅法,启动线程后直接调⽤,例如:Thread t = new AThread(); (); ();⼆、为什么要⽤join()⽅法在很多情况下,主线程⽣成并起动了⼦线程,如果⼦线程⾥要进⾏⼤量的耗时的运算,主线程往往将于⼦线程之前结束,但是如果主线程处理完其他的事务后,需要⽤到⼦线程的处理结果,也就是主线程需要等待⼦线程执⾏完成之后再结束,这个时候就要⽤到join()⽅法了。三、join⽅法的作⽤在JDk的API⾥对于join()⽅法是:即join()的作⽤是:“等待该线程终⽌”,这⾥需要理解的就是该线程是指的主线程等待⼦线程的终⽌。也就是在⼦线程调⽤了join()⽅法后⾯的代码,只有等到⼦线程结束了才能执⾏。四、⽤实例来理解写⼀个简单的例⼦来看⼀下join()的⽤法:d 类1. BThread类2. TestDemo 类class BThread extends Thread { public BThread() { super("[BThread] Thread"); }; public void run() { String threadName = tThread().getName(); n(threadName + " start."); try { for (int i = 0; i < 5; i++) { n(threadName + " loop at " + i); (1000); } n(threadName + " end."); } catch (Exception e) { n("Exception from " + threadName + ".run"); } }}class AThread extends Thread { BThread bt; public AThread(BThread bt) { super("[AThread] Thread"); = bt; } public void run() { String threadName = tThread().getName(); n(threadName + " start."); try { (); n(threadName + " end."); } catch (Exception e) { n("Exception from " + threadName + ".run"); } }}public class TestDemo { public static void main(String[] args) { String threadName = tThread().getName(); n(threadName + " start."); BThread bt = new BThread(); AThread at = new AThread(bt); try { (); (2000); (); (); } catch (Exception e) { n("Exception from main"); } n(threadName + " end!"); }}打印结果:main start. //主线程起动,因为调⽤了(),要等到at结束了,此线程才能向下执⾏。
[BThread] Thread start.
[BThread] Thread loop at 0
[BThread] Thread loop at 1
[AThread] Thread start. //线程at启动,因为调⽤(),等到bt结束了才向下执⾏。
[BThread] Thread loop at 2
[BThread] Thread loop at 3
[BThread] Thread loop at 4
[BThread] Thread end.
[AThread] Thread end. // 线程AThread在();阻塞处起动,向下继续执⾏的结果
main end! //线程AThread结束,此线程在();阻塞处起动,向下继续执⾏的结果。修改⼀下代码:public class TestDemo { public static void main(String[] args) { String threadName = tThread().getName(); n(threadName + " start."); BThread bt = new BThread(); AThread at = new AThread(bt); try { (); (2000); (); //(); //在此处注释掉对join()的调⽤ } catch (Exception e) { n("Exception from main"); } n(threadName + " end!"); }}打印结果:main start. // 主线程起动,因为(2000),主线程没有马上结束;[BThread] Thread start. //线程BThread起动[BThread] Thread loop at 0[BThread] Thread loop at 1main end! // 在sleep两秒后主线程结束,AThread执⾏的();并不会影响到主线程。[AThread] Thread start. //线程at起动,因为调⽤了(),等到bt结束了,此线程才向下执⾏。[BThread] Thread loop at 2[BThread] Thread loop at 3[BThread] Thread loop at 4[BThread] Thread end. //线程BThread结束了[AThread] Thread end. // 线程AThread在();阻塞处起动,向下继续执⾏的结果五、从源码看join()⽅法在AThread的run⽅法⾥,执⾏了();,进⼊看⼀下它的JDK源码:public final void join() throws InterruptedException { join(0L);}然后进⼊join(0L)⽅法:public final synchronized void join(long l) throws InterruptedException{ long l1 = tTimeMillis(); long l2 = 0L; if(l < 0L) throw new IllegalArgumentException("timeout value is negative"); if(l == 0L) for(; isAlive(); wait(0L)); else do { if(!isAlive()) break; long l3 = l - l2; if(l3 <= 0L) break; wait(l3); l2 = tTimeMillis() - l1; } while(true);}单纯从代码上看: * 如果线程被⽣成了,但还未被起动,isAlive()将返回false,调⽤它的join()⽅法是没有作⽤的。将直接继续向下执⾏。 * 在AThread类中的run⽅法中,()是判断bt的active状态,如果bt的isActive()⽅法返回false,在(),这⼀点就不⽤阻塞了,可以继续向下进⾏了。从源码⾥看,wait⽅法中有参数,也就是不⽤唤醒谁,只是不再执⾏wait,向下继续执⾏⽽已。 * 在join()⽅法中,对于isAlive()和wait()⽅法的作⽤对象是个⽐较让⼈困惑的问题: isAlive()⽅法的签名是:public final native boolean isAlive(),也就是说isAlive()是判断当前线程的状态,也就是bt的状态。wait()⽅法在jdk⽂档中的解释如下:Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
In other words, this method behaves exactly as if it simply performs the call wait(0).The current thread must own this object's thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to
wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership
of the monitor and resumes execution.在这⾥,当前线程指的是at。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1689987929a298488.html
评论列表(0条)