双核CPU上运行Notify 与wait的通知丢失现象
大家好,最近写一个多线程程序,用到了wait/notify ,做了个小实验,发现在双核和单核上跑的结果有很大差异
单核上,如java手册上写的一样,双核,则notify不到执行wait的部分,难道是wait在实现上不支持多cpu的问题(如操作系统教材中所说,有些利用中断的原语不能用于多核?)请大家指正
代码如下:
- Java code
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); }}[解决办法]
学习, 帮顶了
[解决办法]
synchronized (b)// 括号里的b是什么意思,起什么作用?
--------------括号里的b是监听器对象,这个对象是可以随意的!但是涉及到多个synchronized时,括号里的对象要保持一致,只有保持一致了,才能够达到想要的同步.
b.wait();// 这一句是什么意思,究竟让谁wait?
肯定是让b去wait啊.
你这个程序我觉得错误就是根本没有了解synchronized的用法啊. 对象没有一致,也既是监听器对象没有一致.导致出现结果在双核和单核上运行的差异,其实你在单核上运行2次的结果也应该是不一样的.因为没有达到同步,结果应该就是随机的.
[解决办法]
synchronized (b)//增加了个锁,锁定了对象b,在同一个类实例中,是线程安全的,但不同的实例还是不安全的。
b.wait();// 让b线程wait
[解决办法]
我觉得你这个程序就是正确的,反正我没看出程序本身哪里有问题
[解决办法]
你可以在b所在的thread启动代码后面让主线程sleep下不就是了
sleep()的时间你可以自己在()里面设置,是以毫秒为单位的
[解决办法]
[解决办法]
学习
[解决办法]
学习了,双核是偶也遇到这个问题
[解决办法]
不是双核的问题,而的你的线程死锁的问题
lz改用一下jdk自带的线程池可以解决这样的问题
根据cpu数量乘以每个cpu的线程数来创建池
[解决办法]
把原始程序改成如下形式,单CPU机器上运行也不能正常退出了。
- Java code
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最终还是要调用系统原句的,你所依赖的工具有问题,就没办法了。