常见的线程不安全类:

  •     StringBuilder:线程不安全,效率高;
  •     StringBuffer:线程安全,使用synchronized做了处理,效率较builder低;

    在一个方法内部,定义局部变量使用,属于堆栈封闭,只有单个线程可以操作这个变量,不涉及线程安全问题。

也就是说,在方法内部使用的话StringBuilder和StringBuffer都是线程安全的,建议使用StringBuilder因为其效率较高。

只有将StringBuilder定义成静态成员变量使用的时候,会造成线程安全问题。(多个线程使用一个变量)

 

  • SimpleDateFormate:线程不安全,
  • JodaTime:线程安全(日期转换 推荐使用)

使用SimpleDateFormate的时候,一定要new SimpleDateFormate()到方法内,使用局部变量堆栈封闭的方式,保证其线程安全,否则多线程访问静态成员变量,会抛出异常。

 

线程不安全的写法:

  • 先检查在执行    if(condition(a)){handle(a);}

   判断和hanle()是原子操作,不可分割,现在两个操作分开执行,如果a对象是一个多线程共享的对象,就会导致线程不安全。

注意:1、使用静态成员变量的时候,会导致多个线程共享同一个变量导致线程安全问题;

           2、使用静态方法时,如果静态方法不涉及到对静态成员变量的处理,是不会导致线程安全问题的;

           3、使用实例成员变量,

                当类是单例的,多个线程对一个实例变量修改会导致线程安全问题

               (如 springMVC的控制器对象)

               (已亲测spring-boot中service是单例的,其成员变量只会实例化一次,

                           会导致线程安全问题,所以以后service中,成员变量要慎用)


                 当类是非单例的,多个线程实例化不同对象,不会导致线程安全问题(如Struts2的控制器对象)。

                     非单例的类的成员变量,要考虑其是否不同线程实例化不同对象,

                     像将该类实例化在方法内就不会造成线程安全问题。

           4、使用方法内局部变量,属于堆栈封闭,不会导致线程安全问题。