Thread之三:ThreadJoin()的用途转载
原创一、join用法
join()和wait()锁不会被释放。,join()是Thread的方法,wait()是Object的方法
1.join方法在中定义Thread类,则调用方必须是线程。
例如:
Thread t = new CustomThread();//这里通常是一个自定义线程类。 t.start();//线程起动 t.join();//被扔到了这里InterruptedException异常
2.上述两行代码也在一个线程中执行。
上面出现了两个线程,其中一个是我们实现的自定义线程类。run方法,做一些我们需要的工作;另一个线程,生成我们的自定义线程类的对象,然后执行
customThread.start(); customThread.join();
在本例中,两个线程之间的关系是一个线程由另一个线程生成并启动,因此让我们将第一个线程视为“ 子线程 ,则另一个线程称为“ 主线程 ”。
2.为什么使用join()方法
主线程生成并启动一个子线程,它执行大量耗时的操作。(在这里,您可以从线程的角色中学习。)当主线程处理完其他事务时,它需要使用子线程的处理结果,这是在此时使用的。join();方法了。
三、join方法的作用
我在网上看到有人说“合并两条线”。我觉得理解这个解释比较麻烦。你为什么不从中学习呢?API在声明中:
“等待线程终止。”
解释说主线程会等待子线程终止。也就是说,在主线程的代码块中,如果遇到t.join()方法,此时主线程需要等待(阻塞),等待子线程结束。(Waits for this thread to die.),继续执行t.join()在代码块之后。
四、示例

class BThread extends Thread { public BThread() { super("[BThread] Thread"); }; public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); try { for (int i = 0; i < 5; i++) { System.out.println(threadName + " loop at " + i); Thread.sleep(1000); } System.out.println(threadName + " end."); } catch (Exception e) { System.out.println("Exception from " + threadName + ".run"); } } } class AThread extends Thread { BThread bt; public AThread(BThread bt) { super("[AThread] Thread"); this.bt = bt; } public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); try { bt.join(); System.out.println(threadName + " end."); } catch (Exception e) { System.out.println("Exception from " + threadName + ".run"); } } } public class TestDemo { public static void main(String[] args) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); BThread bt = new BThread(); AThread at = new AThread(bt); try { bt.start(); Thread.sleep(2000); at.start(); at.join(); } catch (Exception e) { System.out.println("Exception from main"); } System.out.println(threadName + " end!"); } }

结果:

main start. //主线程启动是因为调用at.join(),要等到at结束,则此线程可以向下执行。 [BThread] Thread start. [BThread] Thread loop at 0 [BThread] Thread loop at 1 [AThread] Thread start. //线程at开始是因为呼叫bt.join(),等到bt只有在它结束后,它才会向下执行。 [BThread] Thread loop at 2 [BThread] Thread loop at 3 [BThread] Thread loop at 4 [BThread] Thread end. [AThread] Thread end. // 线程AThread在bt.join();从拦网开始并继续向下的结果 main end! //线程AThread结束,这条线进来了。at.join();从障碍物开始并继续向下的结果。

修改代码:

public class TestDemo { public static void main(String[] args) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start."); BThread bt = new BThread(); AThread at = new AThread(bt); try { bt.start(); Thread.sleep(2000); at.start(); //at.join(); //在这里注释掉这两个人。join()的调用 } catch (Exception e) { System.out.println("Exception from main"); } System.out.println(threadName + " end!"); } }

结果:

main start. // 主线程启动,因为Thread.sleep(2000),则主线程不会立即结束;
[BThread] Thread start. //线程BThread起动 [BThread] Thread loop at 0 [BThread] Thread loop at 1 main end! // 在sleep两秒后,主线程结束,AThread执行的bt.join();不影响主线程。 [AThread] Thread start. //线程at开始吧,因为这通电话。bt.join(),等到bt结束,则此线程向下执行。 [BThread] Thread loop at 2 [BThread] Thread loop at 3 [BThread] Thread loop at 4 [BThread] Thread end. //线程BThread结束了 [AThread] Thread end. // 线程AThread在bt.join();从堵塞处开始并继续向下的结果

5.从源代码开始join()方法
在AThread的run方法,已执行bt.join();,回车查看JDK源码:
public final void join() throws InterruptedException { join(0L); }

public final synchronized void join(long l)
throws InterruptedException
{
long l1 = System.currentTimeMillis();
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 = System.currentTimeMillis() - l1;
} while(true);
}

Join方法被实现。wait(提示:Object 提供的方法)。 当main线程调用t.join时候,main线程获取线程对象。t的锁(wait 这意味着获得对象的锁。),调用对象的wait(等待时间)直到对象被唤醒。main线程 ,如退出后。这意味着main 线程调用t.join必须能拿到线索。t对象的锁。
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除
itfan123


