等待问题后线程通知不工作 - java
Threads notify not working after wait problem - java
我找不到问题有人可以帮助我。
public class Achterbahn {
private final Object monitor = new Object();
public synchronized void test() throws InterruptedException {
//monitor.wait();
System.out.println("car");
wait();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
Thread.sleep(2000);
System.out.println("p");
notify();
//b.t1.notify();
}
public static void main(String []args) throws InterruptedException {
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t5= new Thread(new Runnable() {
@Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
new Thread(t4).start();
new Thread(t5).start();
t5.join();
t4.join();
}
}
输出是:
车
p
似乎通知有效我最后还想打印汽车但我不知道为什么它不起作用
我希望有人能帮助我。尽快。
我在同一个 class 中使用了所有方法,我也尝试了单独的 classes 但它没有用
(我猜在这种情况下,“它没有工作”意味着程序挂起。请具体说明您遇到的问题是什么。)
有两个问题。一个是您在每个线程中创建单独的对象。 wait 和 notify 调用的对象必须是同一个,被等待的 monitor 就是需要接收 notify 的那个。在此代码中,同步方法在调用方法的实例上使用内部锁。
在main方法中创建一次对象,每个线程需要引用同一个对象。
第二个问题,一旦您解决了第一个问题,就会成为竞争条件。如果一个线程执行的通知先发生,那么当等待执行时通知已经发生并且等待永远等待。
添加一个条件变量来记住通知是否发生。
一般来说,模式是在循环中检查条件,参见这个问题:Why we must use "while" for checking race condition not "if"。 post有一个使用变量查看条件是否发生的例子,这里是
synchronized(obj)
{
while (condition_not_matched)
{
obj.wait();
}
//continue
dosomething();
}
你做错了几件事。
- 只启动一个 C 实例。然后使用该实例调用您的方法。不同的实例不在同步方法中共享监视器
- 当您启动它们时,您正在启动两个新线程。只需按如下方式启动它们:
t4.start();
t5.start();
主要问题是t4
先启动然后立即休眠。所以 t5
直到睡眠结束才会开始。但是到那时,t4
中等待的 notify()
已经发出 在 之前 wait()
在 t5
中被调用 因此wait
永远不会看到它。所以你需要给 t4
一个在睡眠发生之前开始的机会。有几种方法可以解决这个问题。一种是使用标志来表示另一种方法已准备就绪。但是不要使用紧密的 while 循环。在里面放一个 sleep
一小段时间。我在下面提供了一个例子。我还为您的线程分配了名称以匹配您的变量。
public class C {
boolean ready = false;
public synchronized void test() throws InterruptedException {
System.out.println("Current thread = " + Thread.currentThread().getName());
ready = true;
System.out.println("car");
wait();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
Thread.sleep(4000);
System.out.println("Current thread = " + Thread.currentThread().getName());
System.out.println("p");
notify();
}
public static void main(String[] args)
throws InterruptedException {
C b = new C();
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
try {
while(!b.ready) {
Thread.sleep(100);
}
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"t4");
Thread t5 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"t5");
System.out.println("Starting t4");
t4.start();
System.out.println("Starting t5");
t5.start();
//
t5.join();
t4.join();
}
}
这段代码对我有用我现在有了 while 循环
public class C {
int i = 34;
public synchronized void test() throws InterruptedException {
System.out.println("car");
while(i == 34) {
wait();
}
notify();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
i = 55;
System.out.println("p");
notify();
}
public static void main(String[] args)
throws InterruptedException {
C b = new C();
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t5 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t4.start();
t5.start();
t4.join();
t5.join();
}
}
我找不到问题有人可以帮助我。
public class Achterbahn {
private final Object monitor = new Object();
public synchronized void test() throws InterruptedException {
//monitor.wait();
System.out.println("car");
wait();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
Thread.sleep(2000);
System.out.println("p");
notify();
//b.t1.notify();
}
public static void main(String []args) throws InterruptedException {
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t5= new Thread(new Runnable() {
@Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
new Thread(t4).start();
new Thread(t5).start();
t5.join();
t4.join();
}
}
输出是: 车 p
似乎通知有效我最后还想打印汽车但我不知道为什么它不起作用
我希望有人能帮助我。尽快。
我在同一个 class 中使用了所有方法,我也尝试了单独的 classes 但它没有用
(我猜在这种情况下,“它没有工作”意味着程序挂起。请具体说明您遇到的问题是什么。)
有两个问题。一个是您在每个线程中创建单独的对象。 wait 和 notify 调用的对象必须是同一个,被等待的 monitor 就是需要接收 notify 的那个。在此代码中,同步方法在调用方法的实例上使用内部锁。
在main方法中创建一次对象,每个线程需要引用同一个对象。
第二个问题,一旦您解决了第一个问题,就会成为竞争条件。如果一个线程执行的通知先发生,那么当等待执行时通知已经发生并且等待永远等待。
添加一个条件变量来记住通知是否发生。
一般来说,模式是在循环中检查条件,参见这个问题:Why we must use "while" for checking race condition not "if"。 post有一个使用变量查看条件是否发生的例子,这里是
synchronized(obj)
{
while (condition_not_matched)
{
obj.wait();
}
//continue
dosomething();
}
你做错了几件事。
- 只启动一个 C 实例。然后使用该实例调用您的方法。不同的实例不在同步方法中共享监视器
- 当您启动它们时,您正在启动两个新线程。只需按如下方式启动它们:
t4.start();
t5.start();
主要问题是t4
先启动然后立即休眠。所以 t5
直到睡眠结束才会开始。但是到那时,t4
中等待的 notify()
已经发出 在 之前 wait()
在 t5
中被调用 因此wait
永远不会看到它。所以你需要给 t4
一个在睡眠发生之前开始的机会。有几种方法可以解决这个问题。一种是使用标志来表示另一种方法已准备就绪。但是不要使用紧密的 while 循环。在里面放一个 sleep
一小段时间。我在下面提供了一个例子。我还为您的线程分配了名称以匹配您的变量。
public class C {
boolean ready = false;
public synchronized void test() throws InterruptedException {
System.out.println("Current thread = " + Thread.currentThread().getName());
ready = true;
System.out.println("car");
wait();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
Thread.sleep(4000);
System.out.println("Current thread = " + Thread.currentThread().getName());
System.out.println("p");
notify();
}
public static void main(String[] args)
throws InterruptedException {
C b = new C();
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
try {
while(!b.ready) {
Thread.sleep(100);
}
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"t4");
Thread t5 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"t5");
System.out.println("Starting t4");
t4.start();
System.out.println("Starting t5");
t5.start();
//
t5.join();
t4.join();
}
}
这段代码对我有用我现在有了 while 循环
public class C {
int i = 34;
public synchronized void test() throws InterruptedException {
System.out.println("car");
while(i == 34) {
wait();
}
notify();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
i = 55;
System.out.println("p");
notify();
}
public static void main(String[] args)
throws InterruptedException {
C b = new C();
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t5 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t4.start();
t5.start();
t4.join();
t5.join();
}
}