• 多线程中使用静态方法存在线程安全的问题


    类的成员分两类,静态成员(static member)和实例成员(instance menber),静态成员属于类,实例成员则属于对象,即类的实例。
    我们知道,静态字段和静态方法的调用都是通过类来调用的,静态方法不会对特定的实例操作,只能调用调用类中的其他属性和静态方法,不能调用类中的非静态属性和非静态方法。实例方法可以对特定的实例操作,既能访问静态属性和静态方法,也能访问实例属性和实例方法。
    在多线程中使用静态方法是否有安全问题?这样看在静态方法中时候使用了静态成员。在多线程中使用一个静态方法的时候,每个线程共享一个静态字段,如果该静态方法不去操作一个静态变量,只在方法内部使用局部变量,则不会造成安全性问题。但是,如果该静态方法操作了一个静态字段,则需要在静态方法中采用互斥访问的方式来对其进行安全处理。

    先来看没有线程安全问题的实例

     public class Test
     {
        public static String hello(String str)
        {
            String tmp = "";
            tmp = tmp + str;
            return tmp;
        }
     }
    

      上述示例中是线程安全的,这是因为在静态方法中声明了局部变量,每个线程在调用的时候,都会创建一份新的局部变量,比如这里的tmp,而不会共享一个存储单元。

       以下是线程不安全的:

       public class Test
     {
       Private static Test test
        public static Test hello()
    {
    If(tets==null)
      Test=new Test();        
    return test;
        }
     }
    

      

    这是因为在静态方法中又返回了静态变量,对于静态变量来说,类在加载的时候会占用同一个存储区,而每个线程都是公用这个存储区的,因此存在线程安全的问题。
    因此在设计工具类的时候,对于没有使用到静态变量的静态工具类方法,是不需要加锁的(synchronized)。
    在使用单例模式做工具类的时候,这个时候静态方法需要被加锁,这是因为所有的线程虽然有自己的方法栈,但是在方法栈中操作的是同一个对象的实体,所以需要进行加锁同步,来实现每个线程都需要等待锁的释放才能使用该对象的引用。
    但是在多例模式做工具类的时候,是不需要加锁的,因为每个线程中有自己的方法栈,但是在方法栈中创建了独立的对象引用,可以看成是线程都是在自己的方法栈中操作局部的对象引用,因此这个时候不需要同步。
    ————————————————
    版权声明:本文为CSDN博主「_花开满楼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_28269905/article/details/72123572

  • 相关阅读:
    flask虚拟环境
    db.Column
    flask_cors跨域请求
    app.config.from_object
    jquery链式原理.html
    swiper轮播
    jquery引用
    animate.html
    设置和获取html里面的内容.html
    jquery获取dom属性方法
  • 原文地址:https://www.cnblogs.com/deepalley/p/16250942.html
Copyright © 2020-2023  润新知