原子性、竞态条件、加锁机制

首先直接上代码:(下面是一段Servlet代码)

    public long getCount(){
        return count;
    }

    public void service(ServletRequest req , ServletResponse resp){
        BigInteger i = extraceFromRequst(req);
        //...事务处理代码
        ++ count;
        //....
    }

上面这个代码是为了统计有多个次访问了Servlet。但是该类是线程不安全的,因为++count看上去只是一个操作,其实是分三步的:读取-修改-写入 ,并且结果状态依赖于之前的状态。所以,当两个线程A和B同时读取到了count的值,那么接下来A修改count后,B的值已经是A修改前读到的值,所以此时的数据就会不准确。这也就是竞态条件。

**静态条件:当某个计算的正确性取决于多个线程的交替执行时,那么就会出现静态条件。**

public class LazyInitRace {
    private Demo demo = null;
    public Demo getDemo(){
        if(demo == null){
            demo = new Demo();
        }
        return demo;
    }
}

上面这段代码也是线程不安全的。例如A和B两个线程同时访问这个代码就会出现读取错误。例如A线程进入了getDemo方法,判断了demo==null,而恰巧此时B线程也到了这一步,所以此时就会创建两个demo对象。这就出现了线程不安全的现象。

上面使用的是延迟初始化静态条件,就是先判断demo是否已经被初始化,然后再初始化。由于缺少原子性操作,所以,线程是不安全的。
所以我么应该对这个代码进行原子性操作。也就是对demo所有的操作封装成一个原子,也就是只能被一个线程同时访问。

**所谓原子操作是指,对于访问同一状态的所有操作(包括操作本身)来说,这个操作是一个以原子方式执行的操作**

而这段代码想要实现线程安全其实加一个synchronized就行了。如下:

    public synchronized Demo getDemo(){
        if(demo == null){
            demo = new Demo();
        }
        return demo;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值