zoukankan      html  css  js  c++  java
  • 闲谈线程安全问题

    一、 什么是线程安全问题?

      谈到线程安全,那么程序必然是运行在多线程的环境中才会有这样的问题。那是不是只要是多线程的应用的代码都有线程安全问题呢?答案显然是否定的,比如我们写的Action就是一个运行在多线程环境中的代码,web服务器接收到一个http请求就会创建一个Thread来处理请求,但是我们的Action为啥没有方法都没有加同步呢?原因是我们的action对象,每次接收到一个http请求(一个Thread),都会重新创建(new)一个新的action对象,就是不同线程使用的action对象是不同的。说完action,我们再说说service吧,如果项目使用了spring,我们都知道spring容器中的对象默认是single(单例),也就是程序中service对象只有一个,那么service对象被不同的线程调用的时候使用的都是一个service对象。所以一般情况下service对象应该是一个无状态的对象,也就是不包含属性,如果在某些情况下,你给一个service定义了一个属性,service方法中对该属性进行了读和写操作,这个时候还要不要考虑线程安全问题呢?答案是非常有必要了!

    你定义的这个属性就是一个被多线程共享的资源,同时多线程有读写操作,就有可能(注意是有可能)存在线程安全问题。

      总结一下判断一个程序存不存在线程安全问题的方法:

      1、 程序运行在多线程环境下吗?

      2、 多线程是否会共享一个资源并且对这个共享资源有读和写操作?

      如果满足以上两点那就非常有必要考虑线程安全问题。

      所以上面的代码就是要考虑线程安全问题了。但是你可能会说为啥我知道可能会有线程安全问题,我却又没有做任何同步处理?原因是这样的,要考虑线程安全问题并不代表一定就有线程安全问题。仿佛有点矛盾。因为我这个业务决定了这里不存在线程安全问题,又或者即使这里发生了线程安全问题,导致的结果是可以预计并且不会对系统产生影响的。所以这里我并没有做同步控制。所以说是判断存不存在线程安全问题,还要根据业务特点和发生问题导致的结果来判断。

    二、 如何解决线程安全问题

    1、 将对象设置成无状态的

    比如上面的service对象尽量不要设置属性,那么这个service对象就是无状态的,多线程使用这个service对象时不存在共享资源问题。

    2、 使用局部对象

    如果上面的activeTimer是一个方法内的对象那么也不存在线程安全问题,因为多线程调用同一个对象的方式时,方法内的对象是私有的。

    3、 如果对象中不得不使用属性时,比如上面的activeTimer必须要设置成service对象属性,那么可以考虑使用ThreadLocal包装属性,包装后的activeTimer就是一个线程安全的,ThreadLocal实际上是为每个线程都重现创建一个activeTimer对象,各线程用自己的activeTimer,也就避免了线程安全问题,当然导致各线程修改的activeTimer不被共享,需要根据自己的业务特点使用。

    4、 当以上3种办法都不适合的时候,终极大招出来了,使用线程同步技术。把读写共享资源的代码块上把锁,给锁起来,让多线程调用这段代码的时候按顺序来访问,这样就不存在线程安全了。Java中实现线程同步(互斥)的方法主要有两种,使用synchronizedlock

    作者:徐飞
    出处:www.cnblogs.com/xumanbu/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    tyvj 1031 热浪 最短路
    【bzoj2005】 [Noi2010]能量采集 数学结论(gcd)
    hdu 1394 Minimum Inversion Number 逆序数/树状数组
    HDU 1698 just a hook 线段树,区间定值,求和
    ZeptoLab Code Rush 2015 C. Om Nom and Candies 暴力
    ZeptoLab Code Rush 2015 B. Om Nom and Dark Park DFS
    ZeptoLab Code Rush 2015 A. King of Thieves 暴力
    hdoj 5199 Gunner map
    hdoj 5198 Strange Class 水题
    vijos 1659 河蟹王国 线段树区间加、区间查询最大值
  • 原文地址:https://www.cnblogs.com/xumanbu/p/4203504.html
Copyright © 2011-2022 走看看