先来举例说明线程不安全是什么状况下发生的:例如一个变量能够被多个线程进行访问,那么在大量线程并发访问这个变量的状况下,线程执行的顺序会给最后的结果带来不可预估的错误。
先定义一个单例类SimpleWorkingHardSingleton:编程
public class SimpleWorkingHardSingleton { private static SimpleWorkingHardSingleton simpleSingleton = new SimpleWorkingHardSingleton(); // 数量 private int count; private SimpleWorkingHardSingleton() { count = 0; } public static SimpleWorkingHardSingleton getInstance() { return simpleSingleton; } public int getCount() { return count; } public void addCount(int increment) { this.count += increment; System.out.println(this.count); } }
能够看到下面这个单例若在多线程环境下运行,count是被多个线程同时操纵的变量,示例:安全
for (int i = 0; i < 5; i++) { new Thread(new Runnable() { @Override public void run() { SimpleWorkingHardSingleton simpleSingleton = SimpleWorkingHardSingleton.getInstance(); simpleSingleton.addCount(1); } }).start(); }
看输出结果(你的执行结果可能和个人不一样):多线程
3 2 2 4 5
匪夷所思的结果,想不懂为何会有两个2出现,1哪儿去了,为何输出不是 1 2 3 4 5,下面就来解释一下并发
其实咱们看到线程安全性的定义的关键点在于正确性,即在多线程的环境下,不管运行时候环境采用如何的调度方式,系统或者类或者方法总能表现出预期的相符的行为,那么就是线程安全的。ide