I am reading Java Concurrency in Practice and encounter the following code snippets. I think the usage of synchronized
is for visibility (let the thread calling generator.get()
see the latest primes
), because the task PrimeGenerator
is executed by one single thread and the internal primes
is not shared with other threads.
Am I right?
Listing 7.1. Using a volatile field to hold cancellation state.
@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);
}
}
Listing 7.2. Generating a second’s worth of prime numbers.
List<BigInteger> aSecondOfPrimes() throws InterruptedException {
PrimeGenerator generator = new PrimeGenerator();
new Thread(generator).start();
try {
SECONDS.sleep(1);
} finally {
generator.cancel();
}
return generator.get();
}