双核CPU上运行Notify 与wait的通知丢失现象
大家好,最近写一个多线程程序,用到了wait/notify ,做了个小实验,发现在双核和单核上跑的结果有很大差异
单核上,如java手册上写的一样,双核,则notify不到执行wait的部分,难道是wait在实现上不支持多cpu的问题(如操作系统教材中所说,有些利用中断的原语不能用于多核?)请大家指正
代码如下:
package thread1;// this program is puzzle when run on 2 core ,I do not know why ,it just// do not stopclass ThreadA { public static void main(String[] args) { ThreadB b = new ThreadB(); b.start(); System.out.println("b is start...."); synchronized (b)// 括号里的b是什么意思,起什么作用? { try { System.out.println("Waiting for b to complete..."); b.wait();// 这一句是什么意思,究竟让谁wait? System.out.println("Completed.Now back to main thread"); } catch (InterruptedException e) { System.out.println("InterruptedException"); } } System.out.println("main:Total is :" + b.total); }}class ThreadB extends Thread { int total; public void run() { synchronized (this) { System.out.println("ThreadB is running.."); for (int i = 0; i < 10; i++) { total += i; System.out.println("total is " + total); } notify(); /* * try { System.out.println("b is waiting" ); wait(); * } catch (InterruptedException e) { System.out.println("InterruptedException"); } */ } System.out.println("AFTER notify"); System.exit(0); }}public class ThreadTest{ public static void main(String[] args) { ThreadB b = new ThreadB(); b.start(); System.out.println("b is start...."); try { Thread.sleep(2000);//没有这个的话,单CPU上运行,成功的可能性很大 } catch (InterruptedException ex) { ex.printStackTrace(); } synchronized (b)// 括号里的b是什么意思,起什么作用? { try { Thread.sleep(2000); System.out.println("Waiting for b to complete..."); b.wait();// 这一句是什么意思,究竟让谁wait? System.out.println("Completed.Now back to main thread"); } catch (InterruptedException e) { System.out.println("InterruptedException"); } } System.out.println("main:Total is :" + b.total); }}class ThreadB extends Thread{ int total; public void run() { synchronized (this) { System.out.println("ThreadB is running.."); for (int i = 0; i < 100; i++) { total += i; System.out.println("total is " + total); } notify(); /* * try { System.out.println("b is waiting" ); wait(); * } catch (InterruptedException e) { * System.out.println("InterruptedException"); } */ } System.out.println("AFTER notify"); }}
[解决办法]
首先,object是用来作为线程的锁的。
调用object.wait()时,当前线程挂起,直到另外一个线程调用object.notify()---当然,如果多个线程wait这个object,就不一定是哪个被唤醒了。
同样,object.notify()唤醒等待该object的一个线程。注意,调用notify的线程在释放锁之前,等待着的线程仍然是不能唤醒的。
这两个方法都必须在synchronized块中进行操作,即当前线程必须拥有该object的锁。
你遇到的问题,如果java的文档中明确写明,双核可能不被支持,那就很可能不被支持了。毕竟wait和notify最终还是要调用系统原句的,你所依赖的工具有问题,就没办法了。