码迷,mamicode.com
首页 > 其他好文 > 详细

ThreadLocal和单例对象比较

时间:2017-12-28 21:40:22      阅读:298      评论:0      收藏:0      [点我收藏+]

标签:map   副本   pos   sys   pre   rgs   tms   random   get   

单例对象: 自始至终只有一个对象

当线程并发,每个线程需要自己独立的资源变量处理不同的业务时,单例对象远远不能满足需求

因此可以采用ThreadLocal模式 : 每个线程有自己独立的资源变量    而且每个线程的资源是独享的  其他线程不能访问和修改

笔者刚开始工作时候使用的Struts2,也曾略读过Struts2源码;就个人而言 虽然和现在对比已经过时,但是Struts2的设计思想还是很不错的,每个请求对应一个Action对象

也是ThreadLocal的代表,除去Struts2的标签和OGNL,整体性能也是不错的,读者有兴趣可以自己研究一下

 

单利模式:

//单例模式 私有构造  只有一个对象
public class Singleton{
    private static Singleton instance = null;
    private Singleton(){}
    public synchronized static Singleton getInstance(){
        if (instance == null) {    
            synchronized (Singleton.class) {    
               if (instance == null) {    
                   instance = new Singleton();   
               }    
            }    
        }    
        return instance;   
    }
}

 

ThreadLocal模式  

  

public class Struts2{
    
    private static ThreadLocal<Struts2> map = new ThreadLocal<Struts2>();
    
    private Struts2(){
        
    }
    
    // synchronized不需要设置    每个线程享有自己独立资源
    public static Struts2 getThreadInstance(){
        Struts2 instance = map.get();
        if(instance == null){
            instance = new Struts2();
            map.set(instance);
        }
        return instance;
    }

    //Strtus2就是这种设计思想
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    
}

//测试类
public
class TestThreadLocal{ public static void main(String[] args) { for(int i=0;i<2;i++){ new Thread(new Runnable(){ @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has put data :" + data); Struts2.getThreadInstance().setMsg(data+""); //存数据 new UserA().get(); new UserB().get(); } }).start(); } } static class UserA{ public void get(){ Struts2 obj = Struts2.getThreadInstance(); System.out.println("UserB from " + Thread.currentThread().getName() + " 数据是 : "+obj.getMsg() ); } } static class UserB{ public void get(){ Struts2 obj = Struts2.getThreadInstance(); System.out.println("UserB from " + Thread.currentThread().getName() + " 数据是 : "+obj.getMsg() ); } } }


输出结果:

Thread-1 has put data :223586296
Thread-0 has put data :1184404572
UserB from Thread-0 数据是 : 1184404572
UserB from Thread-1 数据是 : 223586296
UserB from Thread-1 数据是 : 223586296
UserB from Thread-0 数据是 : 1184404572

 

备注:每个线程有只属于这个线程的对象,每个线程享有自己独立的副本,内部相当于一个Map key[当前线程] - vlaue[值], 线程结束后  会自动把结束的线程移除,不需要自己remove

 

ThreadLocal和单例对象比较

标签:map   副本   pos   sys   pre   rgs   tms   random   get   

原文地址:https://www.cnblogs.com/weishao-lsv/p/8137244.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!