构造函数线程安全-即dubbo的extensionLoader存在线程安全问题

原创 2017年01月03日 17:33:05

构造函数是静态的,而且不管是否为private还是public修饰,他都是静态的。

《JAVA并发编程实战》有提过:

“”如果构造方法暴露了this指针,就会存在线程安全问题“”

其意思是,构造方法是静态的,非线程安全的,如果在这个非线程安全的方法中读写对象的成员,比如初始化对象,就会存在线程安全问题。

比如:

class Holder {

private int n;

public Holder( int n){

this.n = n;

}

}


在dubbo的ExtensionLoader也存在这个问题:

@SuppressWarnings("unchecked")
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
    if (type == null)
        throw new IllegalArgumentException("Extension type == null");
    if(!type.isInterface()) {
        throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
    }
    if(!withExtensionAnnotation(type)) {
        throw new IllegalArgumentException("Extension type(" + type + 
                ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
    }
    
    ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
    if (loader == null) {
        EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
        loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
    }
    return loader;
}

private ExtensionLoader(Class<?> type) {
    this.type = type;
    objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}


下面的构造方法做了非线程安全的赋值操作



 这个extensionLoader的是单例缓存的,在构造的时候没有同步,直接被用来初始化.
所以存在线程安全。

造成的结果:获取扩展类的时候,可能会失败,但这个问题不会影响dubbo的正常时候,只会占用内存



版权声明:本文为博主原创文章,未经博主允许不得转载。

如何解决线程安全问题

 有2种解决方法。 第一,是采用原子变量,毕竟线程安全问题最根本上是由于全局变量和静态变量引起的,只要保证了对于变量的写操作要么全写要么不写,就可以解决线程安全,定义变量用sig_atomic...
  • u012437660
  • u012437660
  • 2016年04月18日 17:15
  • 1142

Java多线程安全问题及解决方案

Java多线程安全问题及解决方案 一、问题引入 通过最常见的多窗口售票问题引入线程安全的问题。代码如下: 注:这里使用Runnable接口来实现线程,这样做是为了共享代售票这个资源,如果我们使用继承T...
  • OONullPointerAlex
  • OONullPointerAlex
  • 2016年03月16日 22:17
  • 1524

servlet线程安全问题的详解

摘 要:介绍了Servlet多线程机制,通过一个实例并结合Java 的内存模型说明引起Servlet线程不安全的原因,给出了保证Servlet线程安全的三种解决方案,并说明三种方案在实际开发中的取舍。...
  • after_you
  • after_you
  • 2017年01月07日 13:28
  • 285

从构造函数看线程安全

线程是编程中常用而且强大的手段,需要面对的就是线程安全问题。Java 中的构造函数是否是线程安全的呢?...
  • wireless_com
  • wireless_com
  • 2017年04月17日 08:29
  • 9420

Android线程安全问题总结

线程安全的定义线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的...
  • u010321471
  • u010321471
  • 2017年02月17日 15:52
  • 1265

java多线程高并发线程安全问题

在抢购之类的业务处理时,会出现超发之类的线程安全问题。 我个人想到的解决方法如下: 采用数据库锁,悲观锁有效率低下问题,所以我推荐乐观锁,虽然会增大CPU开销,很多服务和软件都支持乐观锁,如Redi...
  • qq_36823916
  • qq_36823916
  • 2017年06月26日 11:40
  • 413

什么情况下会有线程安全问题

Q:什么情况下会有线程安全问题 A:当某个实现多线程的线程类中有实例变量时 ps:有状态,无状态对象是什么概念 有状态就是有数据存储功能。有状态对象(Stateful Bean)...
  • feicongcong
  • feicongcong
  • 2017年08月21日 01:12
  • 832

C++学习之STL线程安全性考虑

条款12:对STL容器线程安全性的期待现实一些  标准C++的世界是相当保守和陈旧的。在这个纯洁的世界,所有可执行文件都是静态链接的。不存在内存映射文件和共享内存。没有窗口系统,没有网络,没有数据库...
  • xhu_eternalcc
  • xhu_eternalcc
  • 2014年08月08日 09:13
  • 1152

java-web之servlet中的线程安全问题

一,servlet容器如何同时处理多个请求。 Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求。 线程池实际上是等待执行代码的一组线程叫做工作者线...
  • A1023824314
  • A1023824314
  • 2016年07月25日 00:01
  • 2844

java-ThreadLocal是解决线程安全问题

早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。  ...
  • youdianjinjin
  • youdianjinjin
  • 2016年05月19日 23:20
  • 1893
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:构造函数线程安全-即dubbo的extensionLoader存在线程安全问题
举报原因:
原因补充:

(最多只允许输入30个字)