Thread之三:ThreadJoin()的用途转载

原创
小哥 3年前 (2022-10-27) 阅读数 5 #大杂烩

一、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对象的锁。

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除