【问题标题】:Java Concurrency in Practice "Listing 7.1. Using a volatile field to hold cancellation state.". synchronized for visibility?Java 并发实践“清单 7.1。使用 volatile 字段保持取消状态。”。同步可见性?
【发布时间】:2019-12-31 09:50:14
【问题描述】:

我在阅读Java Concurrency in Practice,遇到如下代码sn-ps。我认为synchronized的使用是为了可见性(让调用generator.get()的线程看到最新的primes),因为任务PrimeGenerator由一个线程执行,内部primes不与其他线程共享线程。

我说的对吗?

清单 7.1。使用 volatile 字段来保持取消状态。

@ThreadSafe
public class PrimeGenerator implements Runnable {
    @GuardedBy("this")
    private final List<BigInteger> primes
            = new ArrayList<BigInteger>();
    private volatile boolean cancelled;

    public void run() {
        BigInteger p = BigInteger.ONE;
        while (!cancelled) {
            p = p.nextProbablePrime();
            synchronized (this) {
                primes.add(p);
            }
        }
    }

    public void cancel() {
        cancelled = true;
    }

    public synchronized List<BigInteger> get() {
        return new ArrayList<BigInteger>(primes);
    }
}

清单 7.2。生成一秒钟的质数。

List<BigInteger> aSecondOfPrimes() throws InterruptedException {
    PrimeGenerator generator = new PrimeGenerator();
    new Thread(generator).start();
    try {
        SECONDS.sleep(1);
    } finally {
        generator.cancel();
    }
    return generator.get();
}

【问题讨论】:

  • 显然如此。还有什么不清楚的吗?我认为 SO 不允许我们给出“是”的答案。
  • @RealSkeptic 不,只是想确保我的理解是正确的。很抱歉提出这样的问题。

标签: java multithreading synchronized


【解决方案1】:

我认为synchronized的用法有两个目的。

  1. 可见性。让阅读线程看到通过添加线程更改的最新primes
  2. 原子性。当读取线程正在读取时,添加线程被阻塞,反之亦然。

【讨论】:

  • 另请参阅此答案:stackoverflow.com/a/34261294/12284870 此外,本书的第 3.1.1 节(“陈旧数据”)(即 Java 并发实践)确认这是确保可见性的一种方式。
猜你喜欢
  • 2020-11-29
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
  • 2011-03-15
  • 1970-01-01
相关资源
最近更新 更多