gpt4 book ai didi

java - 需要对我的等待和通知代码进行一些解释

转载 作者:行者123 更新时间:2023-12-02 06:21:45 25 4
gpt4 key购买 nike

请按照以下代码操作,

资源.java,

public class Resource {

public void first() {

Thread t = Thread.currentThread();
try {
System.out.println(t.getName() + " : is accessing the method 'first' ");

synchronized (this) {
for (int num = 1; num <= 10; num++) {
System.out.println(t.getName() + " : NUM : " + num);
Thread.sleep(500);
if (num == 5) {
this.wait();
}
}
this.notify();
}
} catch (Exception e) {
e.printStackTrace();
}

}

public void second() {

Thread t = Thread.currentThread();
try {
System.out.println(t.getName() + " : is accessing the method 'second' ");

synchronized (this) {
for (int num = 1; num <= 10; num++) {
System.out.println(t.getName() + " : X : " + num);
Thread.sleep(500);
if (num == 7) {
this.notify();
this.wait();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}

}
}

ReqThread.java如下,

public class ReqThread extends Thread{

public ReqThread(String name,Resource res){
this.setName(name);
this.res = res;
}

private Resource res;

@Override
public void run(){
try{
if("ONE".equals(this.getName())){
res.first();
}else{
res.second();
}
}catch(Exception e){
e.printStackTrace();
}
}
}

和MainClass.java,

public class MainClass {
public static void main(String [] args){
Resource res = new Resource();
ReqThread t1 = new ReqThread("ONE", res);
ReqThread t2 = new ReqThread("TWO", res);

t1.start();
t2.start();
}
}

从上面的代码可以看出,我正在尝试学习使用等待和通知机制的线程通信。

这里,线程“ONE”首先启动,然后计数器 5 等待并释放锁,然后线程“TWO”继续(已经处于等待状态),并且其计数器达到 7 通知并等待。

所以我的问题是,当线程“TWO”在方法“第二”中进行通知时,是否会释放锁?

上面代码的输出是

ONE : is accessing the method 'first' 
ONE : NUM : 1
TWO : is accessing the method 'second'
ONE : NUM : 2
ONE : NUM : 3
ONE : NUM : 4
ONE : NUM : 5
TWO : X : 1
TWO : X : 2
TWO : X : 3
TWO : X : 4
TWO : X : 5
TWO : X : 6
TWO : X : 7
ONE : NUM : 6
ONE : NUM : 7
ONE : NUM : 8
ONE : NUM : 9
ONE : NUM : 10
TWO : X : 8
TWO : X : 9
TWO : X : 10

现在,如果我在 Resource.java 中的方法“第二”中进行代码更改,如下所示

if (num == 7) {
this.notify();
//this.wait();
}

代码的输出是

ONE : is accessing the method 'first' 
ONE : NUM : 1
TWO : is accessing the method 'second'
ONE : NUM : 2
ONE : NUM : 3
ONE : NUM : 4
ONE : NUM : 5
TWO : X : 1
TWO : X : 2
TWO : X : 3
TWO : X : 4
TWO : X : 5
TWO : X : 6
TWO : X : 7
TWO : X : 8
TWO : X : 9
TWO : X : 10
ONE : NUM : 6
ONE : NUM : 7
ONE : NUM : 8
ONE : NUM : 9
ONE : NUM : 10

从第二个输出中您可以看到,即使线程“TWO”执行了notify(),它也不会等待并继续打印数字,

这是因为即使线程“TWO”执行了notify(),但代码仍然处于同步块(synchronized block)中,并且它仍然具有尚未释放的锁?

最佳答案

答案在 javadoc 中。 Object#notify()

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object;

所以你是对的。调用 object.notify() 不会释放 object 的监视器。它只是唤醒一个仍然需要竞争才能获得它的线程。

因此 notify() 不会释放监视器,但 wait()确实如此。

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method.

<小时/>

当您熟悉对象同步以及 wait()notify() 的工作方式时,请考虑转向 java.util.concurrent > 包可以为您完成这一切。

关于java - 需要对我的等待和通知代码进行一些解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20953617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com