在if条件内调用Java notify()
我刚刚编写了一个简单的java示例,以熟悉wait和notify方法的概念 其思想是,当调用在if条件内调用Java notify(),java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,我刚刚编写了一个简单的java示例,以熟悉wait和notify方法的概念 其思想是,当调用notify()时,主线程将打印总和 MyThread类 public class MyThread extends Thread { public int times = 0; @Override public void run() { synchronized (this) { try { for (i
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();
}
}
}
}
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);
}
}
}
预期结果
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();
}
}
}
}
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);
}
}
}
5,但我得到了10
嗯,我的想法是,当调用notify()
时,主线程将唤醒并执行System.out.println(t.times)
,它应该给出5。然后,run()
将继续运行,直到完成for循环,该循环将times的值更新为10
非常感谢您的帮助。同步块意味着相互排斥。在任何给定时刻,只允许一个线程持有锁并在同步块中执行代码。这条规则适用于由同一把锁保护的所有区块 在您的例子中,有两个这样的块使用同一个锁,因此允许主线程或
MyThread
在这两个块中执行代码,另一个线程必须等待。因此,这里有以下场景:
wait()
。此调用将释放锁,并将主线程置于等待
状态notify()
。这个调用并没有释放锁,它只是通知主线程它可以在重新获得锁后立即进行时间设置为10,并最终离开同步块,释放锁
println
。但此时,的次数已经是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();
}
}
公共类MyThread扩展线程{
公共不稳定整数倍=0;
@凌驾
公开募捐{
试一试{
对于(int i=0;i<10;i++){
次数+=1;
睡眠(500);
如果(i==5){
已同步(此){
this.notify();
}
}
}
}
}捕获(例外e){
e、 printStackTrace();
}
}
不要忘记将时间设置为volatile,否则JVM不能保证在主线程中看到它的实际值
您还应该了解,这种方法不能保证主线程打印5。可能会出现这样的情况:当第二个线程到达println
调用时,它会进行一次、两次甚至更多的迭代,并且您会看到大于5次的迭代(尽管这非常不幸,因为每次迭代都会调用sleep()
).notify
不会释放锁。请您进一步说明这一点。线程的可能副本不会离开同步块。所以main将无法继续运行,尽管等待可能会返回。谢谢大家。理解。嗯,在这种情况下,我可以用join()来代替。它工作起来很有魅力。谢谢你,安德鲁。非常感谢