线程入门——不恰当的资源共享
线程入门——不恰当的资源共享
pepper_09 发表于6个月前
线程入门——不恰当的资源共享
  • 发表于 6个月前
  • 阅读 4
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

IntGenerator不是runnable类

 

/**
 * 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的地方不出问题,该程序会一直运行下去。

但在实际运行中,一个任务有可能在另一个任务执行第一个对currentEvenValue的递增操作之后,但是没有执行第二个操作之前,调用next()方法,导致next()调用结果为奇数。为证明有可能发生,EvenCheck.test创建了一组EvenChecker对象,并测试检查每个数值是否都为偶数,如果不是,就会报告错误,而程序也会关闭。

 

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 1
博文 17
码字总数 7592
×
pepper_09
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: