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
}
}
Because the getcount method does not use sychronized, when you call the consumer method, the getcount method will also be executed at the same time
Lock or use volatile will ensure that data modifications between multiple threads are visible.