class Resource{
private int count = 0;//用于记录商品的编号
private boolean flag = false;//定义标记用来控制线程的运行交替
//模拟生产行为
public synchronized void set(){
if(flag) //假设换成if, 假设 1.进入线程t1,因为flag为false
try { //5.这时t2进来,也等待,然后执行消费行为的t3,t4
this.wait(); //4.因为flag为true,t1等待
} catch (InterruptedException e) {
e.printStackTrace(); //8.t1醒来,执行以下代码,在打印语句后,t2取得执行权,也打印了一次。
} //2.t1没有执行这段代码
count++;
flag = true;
System.out.println(Thread.currentThread().getName()+"生产。。"+count);
this.notifyAll(); //3.flag变更为true,t1唤醒其他线程,但也可能继续循环,假设继续循环
}
//模拟消费行为
public synchronized void out(){
if(!flag) //6.t3进来,flag为!true,跳过try{}catch{}代码
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = false;
System.out.println(Thread.currentThread().getName()+"消费。。。。。"+count);
this.notifyAll(); //7.flag变更为false, t3唤醒其他线程,假设是t1和t2取得CPU使用权
}
}
//1--8的步骤即线程不安全的原因所在,其实即使是while,该程序还是有微小的可能出错,notifyAll不如Lock系统的Condition的某个对象调用sig
nal()方法
|