java多线程join的使用?
怪我咯
怪我咯 2017-04-18 09:46:58
[Java讨论组]

这段代码是用于验证join方法的使用, 一个线程通过join方法等待另一个线程的执行结束, 按照我的理解, 应该是a和b有序输出, 且主线程一定在b输出之后输出. 但是实际运行结果并不是这样的. 实际的输出如下:

书上讲不光会出现这种情况, 还有可能出现:

threadA sleep start , end
threadB sleep start
main end
threadB sleep end

对于这两种情况该怎么解释呢?
代码如下:

public class Main
{
    public static void main(String[] args)throws Exception
    {
        try {
            ThreadB  b = new ThreadB() ;
            ThreadA a = new ThreadA(b) ;
            a.start();
            b.start();
            b.join(2000) ;//似乎问题的关键就是这一行, 但是我无法解释为什么
            System.out.println("main end");
            Thread.sleep(1);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

class ThreadA extends Thread
{
    private ThreadB b ;

    public ThreadA(ThreadB b) {
        this.b = b;
    }

    @Override
    public void run() {
        try {
            synchronized (b)
            {
                System.out.println("threadA sleep start ....");
                this.sleep(5000) ;
                System.out.println("threadA sleep end....");
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace() ;
        }
    }
}


class ThreadB extends Thread
{
    @Override
    public synchronized void run() {
        try {
            System.out.println("threadB sleep start....");
            this.sleep(5000);
            System.out.println("threadB sleep end....");
        }
        catch (InterruptedException e)
        {
            e.printStackTrace() ;
        }

    }
}
怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(3)
阿神

关键在于

 synchronized (b)
            {
                System.out.println("threadA sleep start ....");
                this.sleep(5000) ;
                System.out.println("threadA sleep end....");
            }

b.join(2000);

这两块代码是互斥的,有一处拿到了锁,另一处就会阻塞在那里。原因是当synchronized的参数是一个对象,那么该对象的synchronized方法都会被阻塞,而join恰恰是synchronized的

这两块代码谁先执行,结合楼主自己说的join的等待时间,会产生各种结果

巴扎黑

我好像明白了.... 问题的关键就在于等待的时间, A会等该5000 , B会等待5000, main只能等2000 , 因此在调用start方法之后, 如果A和B线程只是进入了就绪队列, 并未上CPU执行, 那么main的join方法就会执行, 开始等待, 因此在A或B执行等待2000之后, 就会退出等待, 打印输出.

PHPz

好像是没有在run里面使用synchronized关键字。。要用也是用在Thread对象上

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号