Package thread.concurrencyInPractice.cancellation

Source Code of thread.concurrencyInPractice.cancellation.BrokenPrimeProducer

package thread.concurrencyInPractice.cancellation;

import static java.util.concurrent.TimeUnit.SECONDS;

import java.math.BigInteger;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
* The cancellation mechanism in PrimeGenerator will eventually cause
* the primeseeking task to exit, but it might take a while. If,
* however, a task that uses this approach calls a blocking method
* such as BlockingQueue.put, we could have a more serious problem the
* task might never check the cancellation flag and therefore might
* never terminate.
* <p/>
* The producer thread generates
* primes and places them on a blocking queue. If the producer gets ahead of the consumer, the
* queue will fill up and put will block. What happens if the consumer tries to cancel the producer
* task while it is blocked in put? It can call cancel which will set the cancelled flagbut the
* 108
* producer will never check the flag because it will never emerge from the blocking put (because
* the consumer has stopped retrieving primes from the queue).
*
* @author Sergiy Doroshenko webserg@gmail.com Feb 24, 2009 12:35:09
*         PM
*/
public class BrokenPrimeProducer extends Thread {
    private final BlockingQueue<BigInteger> queue;
    private volatile boolean cancelled = false;

    BrokenPrimeProducer(BlockingQueue<BigInteger> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            BigInteger p = BigInteger.ONE;
            while (!cancelled)    //never checked because put blocked (queue full and waiting for take method)
                queue.put(p = p.nextProbablePrime());
        } catch (InterruptedException consumed) {
        }
    }

    public void cancel() {
        System.out.println("cancel");
        cancelled = true;
    }

    static void consumePrimes() throws InterruptedException {
        BlockingQueue<BigInteger> primes = new LinkedBlockingQueue<>(11);
        BrokenPrimeProducer producer = new BrokenPrimeProducer(primes);
        producer.start();
        try {
            for (int i = 0; i < 12; i++) {
                System.out.println(primes.take());
                SECONDS.sleep(1);
            }
        } finally {
            producer.cancel();
        }
        //task never canceled if you don't use take later after cancel
        //because produser never check cancel flag because queue is full
        //and put method will be wating for take method
        //that may be problem
        //System.out.println(primes.take());
    }

    public static void main(String[] args) throws InterruptedException {
        consumePrimes();
    }
}
TOP

Related Classes of thread.concurrencyInPractice.cancellation.BrokenPrimeProducer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.