Java多线程里面join方法会使被阻塞线程释放对象锁吗?

Java多线程里面join方法会使被阻塞线程释放对象锁吗?
问题描述如下:

public class HelloJava {

    public static void main(String[] args) {
        Object oo = new Object();
        MyThread t1 = new MyThread("线程t1--", oo);
        MyThread t2 = new MyThread("线程t2--", oo);
        t2.start();
        t1.start();
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

class MyThread extends Thread{
    private String name;
    private Object oo;
    public MyThread(String name,Object oo){
        this.name = name;
        this.oo = oo;
    }
    @Override
    public void run() {
        synchronized (oo) {
            for(int i = 0; i < 1000; i++){
                System.out.println(name + i);
            }
        }
    }
}

clipboard.png

锁对象是同一个,从结果来看t1线程调join方法后还是乖乖等着,因为没有拿到锁,那么join方法不会使被阻塞对象释放锁,可是从Thread类源码来看又是调了wait方法的,这是什么情况?求解答。
这是jdk源码:

clipboard.png

阅读 12.3k
5 个回答

oo这把锁,从结果看,t2线程先持有,t2执行完才开始执行t1,这个你应该明白。join方法会造成当前线程wait,就如你看到的这里的wait(0),是当前线程wait,并不是调用者wait,正如join方法的说明一样,Waits for this thread to die. 你的程序里,就是说主线程等到t1线程执行完以后再执行,主线程的wait状态,应该是由t1执行完成之后调用的notify解除,这个是native的,我只是猜测应该是这样。

主线程main执行t1.start()和t2.start()两行代码之后,创建了t1线程和t2线程,它们竞争oo这把锁,谁拿锁谁执行。之后main线程执行t1.join,Thread类中的join方法是同步的,(被synchronized修饰的方法是锁住整个对象的也就是synchronized(t1)),所以main线程拿到了t1这把锁。main线程继续执行t1.join,判断t1这条线程是不是活着的,如果是就调用wait()方法,因为这里调用的是t1.wait,虽然t1是线程,但是在main线程执行的步骤中t1是一把锁,跟object.wait一样,让执行的线程等待,所以这里就让main线程等待了。同时t1、t2线程一直在竞争执行,t1线程的run方法执行完了,t1线程的生命周期也到头了,在API中join方法的描述中说:当线程终止时,调用this.notifyAll方法,t1线程调用了notifyAll,唤醒了main线程.main线程继续判断t1是否存活,因为t1已经执行完run方法了,这时join方法才执行完。
所以join这个方法做的事情是:若线程A(上面的mian线程)调用线程B(t1线程)的join方法,那么线程A(main调用了t1.wait被阻塞)的运行会被暂停,直到线程B(t1线程)运行结束。

新手上路,请多包涵

你这个例子先输出线程2,再输出线程1 的原因仅仅是因为使用 synchronized, 跟 join 的功能没有半毛钱关系。 t1.join 的意思是指 主线程等待 t1线程完成之后才会被唤醒,之前一直是 wait 状态。

新手上路,请多包涵

初学者(刚学到线程这里~)的理解:我们用 synchronized(锁对象) ,锁对象.wait()方法时,释放的是线程的锁对象;而比如s1线程里面添加了s2线程的join()方法,其实是添加了s2.wait()方法,那么这时候释放的是s2这个锁对象,而不是s1线程中synchronized(xx)的这个锁对象xx,除非这个xx锁对象是s2,等等我在看看资料,还有些没弄懂的jion-----

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏