線程入門——不恰當的資源共享

IntGenerator不是runnable類java

 

/**
 * Created by Administrator on 2017/9/6.
 */
public abstract class IntGenerator {
    private volatile boolean canceled = false;

    public abstract int next();

    //Allow this to be canceled
    public void cancel() {
        canceled = true;
    }

    public boolean isCanceled() {
        return canceled;
    }

}

 

/**
 * Created by Administrator on 2017/9/6.
 */
public class EvenGenerator extends IntGenerator {
    private int currentEvenValue = 0;
    public int next(){
        ++currentEvenValue;//danger place
        ++currentEvenValue;
        return currentEvenValue;
    }

    public static void main(String[] args){
        EvenChecker.test(new EvenGenerator());
    }
}

 

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2017/9/6.
 */
public class EvenChecker implements Runnable {
    private IntGenerator intGenerator;
    private final int id;

    public EvenChecker(IntGenerator g, int ident) {
        this.intGenerator = g;
        this.id = ident;
    }

    public void run() {
        while (!intGenerator.isCanceled()) {
            int val = intGenerator.next();
            if (val % 2 != 0) {
                System.out.println(val + "not even");
                intGenerator.cancel();
            }
        }
    }

    public static void test(IntGenerator gp, int count) {
        System.out.println("Press crl+c to exit");
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < count; i++) {
            executorService.execute(new EvenChecker(gp, i));
        }
        executorService.shutdown();
    }

    public static void test(IntGenerator gp) {
        test(gp, 10);
    }
}

正常狀況下,若是標註//danger place的地方不出問題,該程序會一直運行下去。ide

但在實際運行中,一個任務有可能在另外一個任務執行第一個對currentEvenValue的遞增操做以後,可是沒有執行第二個操做以前,調用next()方法,致使next()調用結果爲奇數。爲證實有可能發生,EvenCheck.test建立了一組EvenChecker對象,並測試檢查每一個數值是否都爲偶數,若是不是,就會報告錯誤,而程序也會關閉。測試

相關文章
相關標籤/搜索