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

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

因此可以采用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和单例对象比较的更多相关文章

  1. 设计模式课程 设计模式精讲 8-10 单例设计模式-ThreadLocal线程单例

    1 课程讲解 1.1 应用场景 2 代码演练 2.1 threadLocal应用 1 课程讲解 1.1 应用场景 多线程的时候: 使用同步锁使用时间换空间的方式,(线程排队时间比较长) 而使用thre ...

  2. 010-Scala单例对象、伴生对象实战详解

    010-Scala单例对象.伴生对象实战详解 Scala单例对象详解 函数的最后一行是返回值 子项目 Scala伴生对象代码实战 object对象的私有成员可以直接被class伴生类访问,但是不可以被 ...

  3. apply 伴生对象 单例对象

    apply(): 当类或者对象有一个主要用途时,apply方法提供了很好语法机制 scala> class Foo {} defined class Foo scala> object F ...

  4. Scala单例对象、伴生对象实战详解

    1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...

  5. 不允许在单例对象中创建Srping容器

    spring.net在使用的时候,不允许在单例对象中创建Srping容器 需要将实例化模式转为单例singleton=“false”

  6. 【Cocos2d-X游戏实战开发】捕鱼达人之单例对象的设计(二)

    本系列学习教程使用的是cocos2d-x-2.1.4(最新版为cocos2d-x-2.1.5)    博主发现前两个系列的学习教程被严重抄袭,在这里呼吁大家请尊重开发者的劳动成果, 转载的时候请务必注 ...

  7. iOS 如何创建单例对象

    一.什么是单例? 说到单例我就想起了我的java啊 ,不禁感叹起我的大学时光,学了4年的java开发,到现在还是放弃了我的java,踏入了iOS的行列. 算了,入正轨,我现在正是铁树银花的青春美少女, ...

  8. 【cocos2d-js官方文档】二十五、Cocos2d-JS v3.0中的单例对象

    为何将单例模式移除 在Cocos2d-JS v3.0之前.全部API差点儿都是从Cocos2d-x中移植过来的,这是Cocos2d生态圈统一性的重要一环.可惜的是,这样的统一性也在非常大程度上限制了C ...

  9. Kotlin入门(18)利用单例对象获取时间

    前面介绍了,使用扩展函数可以很方便地扩充数组Array的处理功能,例如交换两个数组元素.求数组的最大元素等等.那么除了数组之外,日期和时间的相关操作,也是很常见的,比如获取当前日期,获取当前时间.获取 ...

随机推荐

  1. 线程局部变量ThreadLocal实现原理

    ThreadLocal,即线程局部变量,用来为每一个使用它的线程维护一个独立的变量副本.这种变量只在线程的生命周期内有效.并且与锁机制那种以时间换取空间的做法不同,ThreadLocal没有任何锁机制 ...

  2. Linux 实操(root密码重置 无法上网 安装xrdp)

    一个是显示器显示不咋地,一个是想远程连接Linux,这样就可以放到下面机房去了.所以想安装一个远程桌面链接.从网上搜了搜,好多.安装的时候需要root权限,但是密码忘了.好吧,开始捣鼓root密码 按 ...

  3. 记一次在mac上源码编译curl,使其支持NSS的过程

    一.背景 在一次学习https原理的过程中,希望客户端指定特定的cipher suites来抓包分析SSL/TLS的握手过程,就想到了使用curl工具,而不是使用浏览器. 接下来使用man curl找 ...

  4. Linux架构之Rsync守护进程推和拉

    第三十三章 Rsync服务 33.1)Rsync基本概述 rsync是一款开源.快速.多功能.可实现全量及增量的本地或远程数据同步备份的优秀工具.rsync软件适用于Unix/linux/Window ...

  5. linux7 grub配置文件 linux6 grub配置文件

    在 grub 的 kernel 配置后面,添加 acpi_pad.disable=1 重启机器之后,开机就不会自动加载 acpi_pad 模块 一:linux6 [root@node2 ~]# cat ...

  6. MySQL WAL

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11447794.html WAL: Write-Ahead Logging 先写日志,再写磁盘.具体说, ...

  7. D0g3_Trash_Pwn_Writeup

    Trash Pwn 下载文件 1 首先使用checksec查看有什么保护 可以发现,有canary保护(Stack),堆栈不可执行(NX),地址随机化没有开启(PIE) 2 使用IDA打开看看 mai ...

  8. 使用PHPExcel操作Excel用法实例分析

    本文实例分析了使用PHPExcel操作Excel用法.分享给大家供大家参考.具体分析如下: PHPExcel下载地址:http://www.codeplex.com/PHPExcel http://w ...

  9. 提示”The following modules are missing or built with a different engine version”

    一台机器使用自行编译版本引擎修改了工程后,另一台机器也使用自行编译版本引擎编辑该工程,有时会出现标题的提示 解决办法: 打开\Engine\Binaries\Win64\UE4Editor.modul ...

  10. 写一个简单易用可扩展vue表单验证插件(vue-validate-easy)

    写一个vue表单验证插件(vue-validate-easy) 需求 目标:简单易用可扩展 如何简单 开发者要做的 写了一个表单,指定一个name,指定其验证规则. 调用提交表单方法,可以获取验证成功 ...