Consumer.run()
里面执行n.conusme()
时,count值为5
但是之后的n.getCount()
得到的是4
public class ThreadDemo {
public static void main(String[] args) {
Apple n = new Apple();
Thread a1 = new Thread(new Producer(n), "Producer");
Thread a2 = new Thread(new Consumer(n), "Consumer");
a1.start();
try{
Thread.sleep(1000) ;
}catch(InterruptedException e){
e.printStackTrace() ;
}
a2.start();
}
}
class Producer implements Runnable {
Apple n;
public Producer(Apple n) {
this.n = n;
}
volatile boolean keepRunning = true;
@Override
public void run() {
while (true) {
while (keepRunning) {
if (n.getCount() < 5) {
n.produce();
System.out.println(Thread.currentThread().getName()
+ " produced an apple," + n.getCount() + " apple(s) left");
}
if (n.getCount() >= 5) {
keepRunning = false;
}
Thread.yield();
}
if (n.getCount() < 5) {
keepRunning = true;
}
}
}
}
class Consumer implements Runnable {
Apple n;
public Consumer(Apple n) {
this.n = n;
}
volatile boolean keepRunning = true;
@Override
public void run() {
while (true) {
while (keepRunning) {
if (n.getCount() <= 5 && n.getCount() > 0) {
n.consume();
System.out.println(Thread.currentThread().getName()
+ " consumed an apple," + n.getCount() + " apple(s) left");////here is 5
}
if (n.getCount() <= 0) {
keepRunning = false;
}
Thread.yield();
}
if (n.getCount() > 0) {
keepRunning = true;
}
}
}
}
class Apple {
private int count = 0;
public int getCount() {
return count;
}
public synchronized void produce() {
count++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void consume() {
count--;
System.out.println("count="+count);//here is 4
}
}
因為getcount方法沒有使用sychronized,所以當你呼叫consumer方法時,getcount方法也會同時執行
加鎖 或是 使用volatile 會保證多執行緒間資料的修改是可見的。