如何将数据更新到主内存?

时间:2015-04-08 07:03:34

标签: java synchronized java-memory-model

            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

                }

n.consume()已更改计数(计数为4),但n.getCount()仍为5。 如何将数据更新到主内存,以便n.getCount可以获取更新的count

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() {
        this.count++;

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void consume() {
        this.count--;//here is 4
    }

}

2 个答案:

答案 0 :(得分:1)

您需要同步count变量的所有访问,包括读取。在您的情况下,您需要同步getCount()

public synchronized int getCount() {
    return count;
}

答案 1 :(得分:0)

将Apple中的count变量标记为volatile。这将强制JVM从主内存中读取此变量并覆盖缓存