Maz*_*zen 4 java multithreading notify wait
我刚刚编写了一个简单的java示例来熟悉wait和notify方法的概念.
这个想法是,在调用时notify(),主线程将打印总和.
MyThread类
public class MyThread extends Thread {
public int times = 0;
@Override
public void run() {
synchronized (this) {
try {
for (int i = 0; i < 10; i++) {
times += 1;
Thread.sleep(500);
if (i == 5) {
this.notify();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
主类
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
synchronized (t) {
t.start();
try {
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(t.times);
}
}
}
Run Code Online (Sandbox Code Playgroud)
预期成绩
5但我得了10.
好吧,我认为,当notify()调用时,主线程将唤醒并执行System.out.println(t.times)应该给出的5.然后run()将继续直到它完成for循环,这将把时间值更新为10.
任何帮助都非常感谢.
同步块意味着互斥.在任何给定时刻,只允许一个线程持有锁并在同步块内执行代码.此规则分布在由同一个锁保护的所有块上.
在你的情况下,有两个这样的块使用相同的锁,所以它是主线程或MyThread允许在这些块中的任何一个块中执行代码,另一个线程必须等待.那么,这里有以下场景:
wait().此调用释放锁并将主线程置于WAITING状态.notify().此调用不释放锁,它只是通知主线程一旦可以重新获取锁就可以进行.times为10并最终离开同步块,释放锁定.println.但到了这个时候,times已经是10了.使用join()对您没有帮助,因为结果将是相同的 - 主线程只能在第二个完成时进行.
如果您希望主线程在第二个线程命中5后立即继续执行,则需要获取锁定并在该事件之后立即释放它:
public class MyThread extends Thread {
public volatile int times = 0;
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
times += 1;
Thread.sleep(500);
if (i == 5) {
synchronized(this) {
this.notify();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记使用timesvolatile,否则JVM不能保证你会在主线程中看到它的实际值.
你还应该明白,这种方法并不能保证你的主线程打印5.可能会发生这种情况,当它到达println调用时,第二个线程会进行一次或两次甚至更多的迭代,你会看到比5(尽管由于sleep()每次迭代调用而非常不幸).
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |