线程通知等待后不工作问题-java

3j86kqsm  于 2021-06-29  发布在  Java
关注(0)|答案(3)|浏览(443)

我找不到问题,有人能帮我吗。

  1. public class Achterbahn {
  2. private final Object monitor = new Object();
  3. public synchronized void test() throws InterruptedException {
  4. //monitor.wait();
  5. System.out.println("car");
  6. wait();
  7. System.out.println("car");
  8. }
  9. public synchronized void Passagier() throws InterruptedException {
  10. Thread.sleep(2000);
  11. System.out.println("p");
  12. notify();
  13. //b.t1.notify();
  14. }
  15. public static void main(String []args) throws InterruptedException {
  16. Thread t4 = new Thread(new Runnable() {
  17. @Override
  18. public void run() {
  19. Achterbahn b = new Achterbahn();
  20. try {
  21. b.Passagier();
  22. } catch (InterruptedException e) {
  23. // TODO Auto-generated catch block
  24. e.printStackTrace();
  25. }
  26. }
  27. });
  28. Thread t5= new Thread(new Runnable() {
  29. @Override
  30. public void run() {
  31. Achterbahn b = new Achterbahn();
  32. try {
  33. b.test();
  34. } catch (InterruptedException e) {
  35. // TODO Auto-generated catch block
  36. e.printStackTrace();
  37. }
  38. }
  39. });
  40. new Thread(t4).start();
  41. new Thread(t5).start();
  42. t5.join();
  43. t4.join();
  44. }
  45. }

输出为:p车
它似乎是通知工作,我想打印也车在最后,但我不知道为什么它不工作
我希望有人能帮助我。尽快。
我在同一个类中有所有的方法,我也尝试过sepreate类,但是没有用

2admgd59

2admgd591#

你做错了好几件事。
只启动c的一个示例。然后使用该示例调用您的方法。不同的示例在同步方法中不共享监视器
当你开始两个新的线程的时候。只需按如下方式启动它们:

  1. t4.start();
  2. t5.start();

主要问题是 t4 先开始,然后马上睡觉。所以呢 t5 直到睡眠结束才开始。但到那时 notify() 等待 t4wait() 在中调用 t5 因此 wait 我永远也看不到。所以你需要付出 t4 在睡觉前开始的机会。有几种方法可以解决这个问题。一种是使用一个标志来表示另一种方法已经就绪。但不要使用紧密的while循环。放一个 sleep 在里面呆了一小段时间。我在下面举了一个例子。我还为线程分配了名称以匹配变量。

  1. public class C {
  2. boolean ready = false;
  3. public synchronized void test() throws InterruptedException {
  4. System.out.println("Current thread = " + Thread.currentThread().getName());
  5. ready = true;
  6. System.out.println("car");
  7. wait();
  8. System.out.println("car");
  9. }
  10. public synchronized void Passagier() throws InterruptedException {
  11. Thread.sleep(4000);
  12. System.out.println("Current thread = " + Thread.currentThread().getName());
  13. System.out.println("p");
  14. notify();
  15. }
  16. public static void main(String[] args)
  17. throws InterruptedException {
  18. C b = new C();
  19. Thread t4 = new Thread(new Runnable() {
  20. @Override
  21. public void run() {
  22. try {
  23. while(!b.ready) {
  24. Thread.sleep(100);
  25. }
  26. b.Passagier();
  27. } catch (InterruptedException e) {
  28. // TODO Auto-generated catch block
  29. e.printStackTrace();
  30. }
  31. }
  32. },"t4");
  33. Thread t5 = new Thread(new Runnable() {
  34. @Override
  35. public void run() {
  36. try {
  37. b.test();
  38. } catch (InterruptedException e) {
  39. // TODO Auto-generated catch block
  40. e.printStackTrace();
  41. }
  42. }
  43. },"t5");
  44. System.out.println("Starting t4");
  45. t4.start();
  46. System.out.println("Starting t5");
  47. t5.start();
  48. //
  49. t5.join();
  50. t4.join();
  51. }
  52. }
展开查看全部
xoefb8l8

xoefb8l82#

(我猜在这种情况下,“它没有工作”意味着程序挂起。请具体说明您看到的问题。)
有两个问题。一种是在每个线程中创建单独的对象。调用wait和notify的对象必须相同,等待的监视器是需要接收notify的监视器。在这段代码中,同步方法在调用方法的示例上使用内在锁。
在main方法中创建一次对象,每个线程需要引用同一个对象。
第二个问题,一旦你解决了第一个问题,将是一个竞赛条件。如果由一个线程执行的notify首先发生,那么当wait执行时,notify已经发生,并且wait将永远等待。
添加条件变量以记住是否发生了通知。
一般来说,模式是检查循环中的条件,请看这个问题:为什么我们必须使用“while”来检查竞争条件而不是“if”。post有一个使用变量查看是否发生了条件的示例,这里是

  1. synchronized(obj)
  2. {
  3. while (condition_not_matched)
  4. {
  5. obj.wait();
  6. }
  7. //continue
  8. dosomething();
  9. }
rfbsl7qr

rfbsl7qr3#

这个代码对我有用我现在有了while循环

  1. public class C {
  2. int i = 34;
  3. public synchronized void test() throws InterruptedException {
  4. System.out.println("car");
  5. while(i == 34) {
  6. wait();
  7. }
  8. notify();
  9. System.out.println("car");
  10. }
  11. public synchronized void Passagier() throws InterruptedException {
  12. i = 55;
  13. System.out.println("p");
  14. notify();
  15. }
  16. public static void main(String[] args)
  17. throws InterruptedException {
  18. C b = new C();
  19. Thread t4 = new Thread(new Runnable() {
  20. @Override
  21. public void run() {
  22. try {
  23. b.Passagier();
  24. } catch (InterruptedException e) {
  25. // TODO Auto-generated catch block
  26. e.printStackTrace();
  27. }
  28. }
  29. });
  30. Thread t5 = new Thread(new Runnable() {
  31. @Override
  32. public void run() {
  33. try {
  34. b.test();
  35. } catch (InterruptedException e) {
  36. // TODO Auto-generated catch block
  37. e.printStackTrace();
  38. }
  39. }
  40. });
  41. t4.start();
  42. t5.start();
  43. t4.join();
  44. t5.join();
  45. }
  46. }
展开查看全部

相关问题