gpt4 book ai didi

java - 与我在java中修改同步代码的结果感到困惑

转载 作者:行者123 更新时间:2023-12-01 12:29:14 24 4
gpt4 key购买 nike

这是原始代码:

// Demonstrating multithreading and thread synchronization in Java
public class ForkExample implements Runnable {

int i; // the ID of the thread, so we can control behavior
boolean busy; // the flag, Thread 1 will wait until Thread 0 is no longer busy before continuing
ForkExample other; // reference to the other thread we will synchronize on. This is needed so we can control behavior.

// create the runnable object
public ForkExample(int i, ForkExample other) {
this.i = i; // set the thread ID (0 or 1)
if (i == 0)
busy = true; // set the busy flag so Thread 1 waits for Thread 0
else
this.other = other;
}

// synchronized method to test if thread is busy or not
public synchronized boolean isBusy() {
return busy;
} // What happens if this isn't synchronized?

// run method needed by runnable interface
public void run() {
if(i == 0) // 1st thread, sleep for a while, then notify threads waiting
try {
Thread.sleep(4000); // What happens if you put this sleep inside the synchronized block?
synchronized(this) {
notify(); // notify() will only notify threads waiting on *this* object;
}
Thread.sleep(4000); // What happens if you put this sleep inside the synchronized block?
synchronized(this) {
busy = false; // must synchronize while editing the flag
notify(); // notify() will only notify threads waiting on *this* object;
}
} catch(InterruptedException tie) {
tie.printStackTrace();
}
else {
while(other.isBusy()) { // check if other thread is still working
System.out.println("Waiting!");
// must sychnronize to wait on other object
try {
synchronized(other) {
other.wait();
}
} // note we have synchronized on the object we are going to wait on
catch(InterruptedException tie) {
tie.printStackTrace();
}
}
System.out.println("Finished!");
}
}

public static void main(String[] args) {
ForkExample t1 = new ForkExample(0, null);
ForkExample t2 = new ForkExample(1, t1);
(new Thread(t2)).start();
(new Thread(t1)).start();
}

}

这是经过我修改的原始代码:

// Demonstrating multithreading and thread synchronization in Java
public class ForkExample implements Runnable {

// the ID of the thread, so we can control behavior
int i;
// the flag, Thread 1 will wait until Thread 0 is no longer busy before continuing
boolean busy;
// reference to the other thread we will synchronize on. This is needed so we can control behavior.
ForkExample other;

// create the runnable object
public ForkExample(int i, ForkExample other) {
this.i = i; // set the thread ID (0 or 1)
if (i == 0)
busy = true; // set the busy flag so Thread 1 waits for Thread 0
else
this.other = other;
}

// synchronized method to test if thread is busy or not
public boolean isBusy() {
if (busy) /*** Added if/else statement to tell user if the thread is still busy. ***/
System.out.print("Still busy, ");
else
System.out.print("Thread is no longer busy, ");
return busy;
} // What happens if this isn't synchronized?
/*** Method still works even without being synchronized ***/

// run method needed by runnable interface
public void run() {
if(i == 0) // 1st thread, sleep for a while, then notify threads waiting
try {
synchronized(this) {
Thread.sleep(4000); // What happens if you put this sleep inside the synchronized block?
/*** All statements in this block still goes through after notify(), but t1 is asleep ***/
System.out.println("yo");
notify(); // notify() will only notify threads waiting on *this* object;
/*** This notify doesn't work ***/
System.out.println("sup");
}
System.out.println("stop synchronization");
/*** somehow forces synchronized(this) as another method call ***/
synchronized(this) {
System.out.println("hey");
Thread.sleep(1000); // What happens if you put this sleep inside the synchronized block?
System.out.println("hello");
busy = false; // must synchronize while editing the flag
notify(); // notify() will only notify threads waiting on *this* object;
/*** This notify does not work either ***/
System.out.println("que?");
}
synchronized(this) {
System.out.println("yes");
notify();
/*** This notify works if the "stop synchronization statement exists ***/
}
Thread.sleep(1000);
synchronized(this) {
System.out.println("hey again");
notify();
}
/*** Other thread finally executes since t1 sleeps for 1 second ***/
} catch(InterruptedException tie) {
tie.printStackTrace();
}
else {
while(other.isBusy()) { // check if other thread is still working
System.out.println("Waiting!");
// must synchronize to wait on other object
try { synchronized(other) { other.wait(); } }
// note we have synchronized on the object we are going to wait on
catch(InterruptedException tie) { tie.printStackTrace(); }
System.out.println("All threads done!");
/*** Sysout here since this mod allows only one pass ***/
}
System.out.println("Wrapping up..."); /*** Lets user know that finishing will take a moment. ***/
try {
Thread.sleep(3000);
} catch (InterruptedException tie) {
tie.printStackTrace();
}
System.out.println("Finished!");
}
}

public static void main(String[] args) {
ForkExample t1 = new ForkExample(0, null);
ForkExample t2 = new ForkExample(1, t1);
(new Thread(t2)).start();
(new Thread(t1)).start();
System.out.println("End of Main method"); /*** Added sysout to see how threads work ***/
}

}

这是输出:

End of Main method
Still busy, Waiting!
yo
sup
stop synchronization
hey
hello
que?
yes
All threads done!
Thread is no longer busy, Wrapping up...
hey again
Finished!

为什么第三个 notify() 是唯一一次执行?

最佳答案

首先,Thread#sleep(long) 不会放弃任何已获取的对象锁。

您的应用程序基本上是一个大的竞争条件,并且由线程调度程序自行决定发生。

唯一重要的notify()是在wait()之后发生的。 javadoc of notify()

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.

因此,无论哪个线程实际上唤醒了另一个线程,该另一个线程仍然必须在 synchronized block 内等待,直到调用线程释放锁,即。离开 synchronized block (并且不进入另一个 synchronized block )。

关于java - 与我在java中修改同步代码的结果感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26081392/

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