小编典典

每当我更改同步关键字的位置时,wait(n)的行为就不同

java

参考下面的代码

     public void acquire(){
        synchronized(a){
            print("acquire()");
            try{
                //Thread.sleep(5000);
                synchronized(this){
                    wait(5000);
                }
                print("I have awoken");
                print("" + a);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        print("Leaving acquire()");
    }


    public void modify(int n){
        print("Entered in modfy");
        synchronized(a){
            try{
                //Thread.sleep(5000);
                synchronized(this){
                    wait(5000);
                }
                this.a=n;
                print("new value" + a);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

        final SynchoTest ttObj = new SynchoTest();
        Thread A = new Thread(new Runnable(){
            public void run() {
                ttObj.acquire();    
            }
        },"A");

        Thread B = new Thread(new Runnable(){
            public void run() {
                ttObj.modify(97);   
            }
        },"B");
        A.start();
        B.start();

据我所知,wait(n)会暂停线程,直到调用notify()/ notifyAll()或指定的时间n结束为止。

但…

  • 在上面的方法中,如果我像使用Thread.sleep(n)一样直接使用wait(n),则会得到运行时异常。
  • 如果我同步这两个方法,而不是将wait(n)包含在同步块中,那么我没有收到任何异常,但是两个线程都将永远被阻塞。
  • 但是,如果我确实喜欢在同步块周围附加即wait(n),则它工作正常。

请告诉我为什么?还告诉我,如果我使用sleep(n)而不是wait(n),为什么在定位同步块上没有什么不同?

我的问题是关于关键字的各个位置上的wait(n)的各种结果。

@灰色

notify()或notifyAll()和wait()必须在您正在等待的对象的同步块中

向我解释了为什么我通过将同步块放置在各个位置来获取运行时异常。

现在请解释一下为什么

public void method(){
    synchronized(a){
        synchronized(this){
            wait(n);
        }
    }
}

工作正常。但

public synchronized void method(){
    synchronized(a){
        wait(n);
    }
}

永远阻塞我的线程。


阅读 279

收藏
2020-11-30

共1个答案

小编典典

与定位同步关键字无关。由于您锁定了另一个对象并尝试等待另一个对象,因此您面临问题。好吧,@ Gray已经对此进行了解释,因此不再重复。

对于您的另一个问题,关于为什么两个线程都被阻塞;

线程A:锁定此[A:可运行]

线程A:锁定[A:可运行]

线程B:正在等待[A:可运行,B:已阻止]

线程A:释放该线程(表示等待)[A:定时等待,B:已阻止]

线程B:锁定此线程[A:定时等待,B:可运行]

线程B:等待已被线程A锁定的线程[A:定时等待,B:已阻止]

线程A:等待被线程B锁定的线程[A:已阻止,B:已阻止]

2020-11-30