线程安全(一):多线程竞态条件导致的线程不安全

  1. 什么是线程安全?
         当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么这个类就是线程安全的。

  2. 状态变量出现线程不安全的解决办法?
         ① 在访问状态变量时使用同步
         ②将状态变量修改为不可变的变 的变量
         ③不在线程之间共享该变量

  3. 竞态条件的产生导致的线程不安全

    1. 3.1 竞态条件(Race Condition):计算正确性取决于 多线程交替执行的时序时,就会产生竞态条件。

    1. 3.2 竞态条件产生线程安全的示例:
      1. 示例一: 在没有线程同步的情况下统计已处理请求数量的Servlet

public class UnsafeCountingFactory implements Servlet{
    private long count;
    public long getCount(){return count;}
    public void service(ServletRequest req,ServletResponse resp){
             ++count;
}

}

  1. 当线程在执行++count时,实际上包含三个独立的操作:读取count的当前值,将其加1,然后将计算结果返回给count.这是一个 “读取-修改-写入”的操作时列,其结果状态依赖于之前线程操作的状态。所以当线程A,B执行结果可能会出现以下糟糕的情况:

这里写图片描述

  1. 示例二:延迟初始化问题
public class LazyInitRace{
    private ExpensiveObject instance=null;
        public ExpensiveObject getInstance(){
        if(instance==null)
           instance=new ExpensiveObject();
        return instance;
}
}
  1.     在LazyInitRace 中假定线程A和线程B同时执行getInstacance()。A看到instance为空,进入if条件语句,而此时线程B也执行到if条件语句,判断instance 同样为空,也进入if条件语句。因而线程A和线程B各自创建了一个创建一个新的ExpensiveObject实例,导致两次调用getInstance()得到不同的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值