单例模式在多线程中的使用情况
废话不多说,直接上代码:
class MyThreadScopeData{
private MyThreadScopeData(){}
private static MyThreadScopeData instance;
//单例设计模式
public static MyThreadScopeData getInstance(){
if(instance ==null){
instance = new MyThreadScopeData();
}
return instance;
}
}
上述代码中,如果直接用于多线程中是存在问题的,比如线程A调用MyThreadScopeData.getInstance()获取MyThreadScopeData对象,执行到 instance = new MyThreadScopeData();还没返回的时候恰好这时候线程B也来调用MyThreadScopeData.getInstance(),执行了 instance = new MyThreadScopeData();这时候则线程B创建的对象会覆盖线程A创建的对象。所以在线程A中的MyThreadScopeData对象其实已经发生了变化,在实际操作过程中会存在问题。如何避免这种情况呢,就要用到线程中的共享变量问题了,这就要涉及到对ThreadLocal类的使用。这时可以将上面的代码修改如下:
class MyThreadScopeData{
private MyThreadScopeData(){}
//单例设计模式
//定义ThreadLocal
private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
public static MyThreadScopeData getThreadInstance(){
MyThreadScopeData instance = map.get();
if(instance ==null){
instance = new MyThreadScopeData();
map.set(instance);
}
return instance;
}
}
在单例类中定义一个ThreadLocal对象用于存储这个类本身的对象,当线程A调用MyThreadScopeData getThreadInstance()方法获取MyThreadScopeData
对象的时候,首先从ThreadLocal中获取保存在线程A中的MyThreadScopeData
对象,如果没有,则创建一个新的MyThreadScopeData
对象,将此对象保存在ThreadLocal对象中,然后返回MyThreadScopeData 对象;当线程B调用MyThreadScopeData
getThreadInstance()方法获取MyThreadScopeData 对象的时候,流程和线程A调用MyThreadScopeData getThreadInstance()方法一样。此时线程A和线程B各自保存和操作自己线程范围内的MyThreadScopeData
对象和数据。这就做到了线程内部的数据是共享的,而线程与线程之间的数据是独立的。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。