class Q {
int n;
boolean valueset = false; synchronized int get() {
if (!valueset)
try {
wait();
} catch (InterruptedException e) {
}//else{
System.out.println("got:" + n);
valueset = false;
notify();
//}
return n;
} synchronized void put(int n) {
if (valueset)
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}//else{
this.n = n;
valueset = true;
System.out.println("put: " + n);
notify();
//}
}
}class Producer implements Runnable {
Q q; Producer(Q q) {
this.q = q;
new Thread(this, "producer").start();
} public void run() {
// TODO Auto-generated method stub
int i = 0;
while (true) {
q.put(i++);
}
}}class Consumer implements Runnable {
Q q; Consumer(Q q) {
this.q = q;
new Thread(this, "consumer").start();
} public void run() {
// TODO Auto-generated method stub
while (true) {
q.get();
}
}}public class PC { /**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("press Control c to stop");
}}
在Q中去掉//和不去掉//有何区别!为什么运行结果不一样?

解决方案 »

  1.   

    去掉//时:
    假如valueset为false,则进入if,而且当wait()结束后会直接跳到else{}的后面,不会执行else{}内部的代码。也就是说只有当valueset为true时else{}中的代码才会被执行不去掉//时:
    无论valueset为什么值都会执行if{}之后的代码。所以两种结果当然会不同。这是逻辑问题,并不是线程问题
      

  2.   

    不是每个if都要带上else的操作的。
      

  3.   

    Java中线程同步的锁是对象的锁,我们称之为Monitor,监视器!q只是内存中一个对象,相当于资源,当Producer和Consumer进入同步代码块也就是synchronized方法时或获得q的Monitor,也就是对象锁wait会释放所有的锁起源,所以Producer调用wait时候会释放锁,对应Consumer就会得到锁,只有得到锁才能进入Synchronized代码块,如果不加else的话逻辑上其实是存在错误的get和put很可能都只有一半方法会一直跑,一个上半部分一个下半部分……至于谁先跑,无权控制,看CPU的时间片先分给哪个线程对多线程编程的时候一定要慎重,理解清楚锁和CPU时间片