线程不安全会发生什么问题?

线程不安全会发生什么问题?

问题描述:

线程不安全会发生什么问题?
线程不安全会发生什么问题?
线程不安全会发生什么问题?

举例:
两个线程共享一个堆上的公共变量a
线程1和线程2都有如下代码
int c = a;
c = c + 1;
a = c; //实际上可能写的是a++,但是a++看上去是原子的,为了演示,写成如上的形式。
假设a=100,按照预期,两个线程各执行一次,结果应该是102,但是可能出现101:
线程1:c = a; c = c +1;,此时c = 101,线程2执行c = a,此时a还是100,c = c + 1,c= 101。然后线程1写回101,线程2也写回101。

程序运行结果出错,死锁,等等

关于死锁,举例:
线程1锁住a,等待b
在此过程中,如果线程2占用的是b,并且等待a,那么两个线程会无限等待下去,这就是姜昆小品中说的“工厂不给幼儿园开介绍信,幼儿园没有义务给工厂开介绍信;没有幼儿园的介绍信,工厂没有义务先给幼儿园开介绍信”

有的时候会发生更糟糕的事情,比如说第一个程序,C++中一个线程释放了指针,另一个线程还在使用这个指针,那么有可能会破坏内存,导致不可预知的问题。

不能按照你写的逻辑得到正确的结果!例如你要计数,如果你不是线程安全的,可能你获得计数结果就是错误的!

多线程带来的风险有三种,安全性问题,活跃性问题,性能问题。
首先,安全性问题,《Java并发编程》一书中对类的线程安全的定义是:当多个线程访问某个类时,不管运行环境采用何种调度方式或者这些线程将如何交替执行,并且在主调用代码中不需要任何额外的同步或者协同,这个类都能表现正确的行为,那么这个类就是线程安全的。
相反这段描述的另一面就是线程不安全的,即可能出现某个类的行为与其规范的不一致。例如:数值序列生成器,简单的共享变量++操作。

 public class UnsafeSequence{
     private int value;
         public int getNext(){
             return value++;
        }
 }

这段代码的getNext如果执行时机不对,那么两个线程在调用getNext时会得到相同的值,因为value++操作本身包含三种独立的操作,读value,value+1,写入value,这三个动作如果在多个线程之间交替执行,就可能导致最终的数据不合常理。也就是说这段代码存在安全性问题。
其次,活跃性问题是指当某个操作无法继续执行下去时就会发生活跃性问题,如锁机制下线程死锁的问题。
最后,性能问题,多线程程序中,线程的调度,频繁的上下文切换等操作会带来极大的开销,也是编写多线程应用需要权衡的问题。

最好自己写个测试,最常见的就是数据出错,

有可能出现多个线程先后更改数据,从而造成所得到的数据是脏数据。