线程学习--(六)单例和多线程、ThreadLocal

一、ThreadLocal

使用wait/notify方式实现的线程安全,性能将受到很大影响。解决方案是用空间换时间,不用锁也能实现线程安全。

来看一个小例子,在线程内的set、get就是threadLocal

package thread2;

public class ConnThreadLocal {

    public static ThreadLocal<String> th = new ThreadLocal<String>();

    public void setTh(String value){
        th.set(value);
    }
    public void getTh(){
        System.out.println(Thread.currentThread().getName() + ":" + this.th.get());
    }

    public static void main(String[] args) throws InterruptedException {

        final ConnThreadLocal ct = new ConnThreadLocal();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                ct.setTh("abc");
                ct.getTh();
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    ct.getTh();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t2");

        t1.start();
        t2.start();
    }

}

二、单例和多线程

单例常见的有饥饿模式和懒汉模式,但是这两个模式在多线程情况下是不行的。在多线程中考虑到新能和线程安全的问题一般考虑double check instance 和 static inner class这两种方式实现单例模式。

static inner class方式:

package bhz.base.conn011;

public class Singletion {

    private static class InnerSingletion {
        private static Singletion single = new Singletion();
    }

    public static Singletion getInstance(){
        return InnerSingletion.single;
    }

}

double check instance 方式:

package thread2;

public class DubbleSingleton {

    private static DubbleSingleton ds;

    public  static DubbleSingleton getDs(){
        if(ds == null){
            synchronized (DubbleSingleton.class) {
                if(ds == null){
                    ds = new DubbleSingleton();
                }
            }
        }
        return ds;
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t2");
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t3");

        t1.start();
        t2.start();
        t3.start();
    }

}

时间: 2024-12-21 20:06:02

线程学习--(六)单例和多线程、ThreadLocal的相关文章

架构师养成记--6.单例和多线程、ThreadLocal

一.ThreadLocal 使用wait/notify方式实现的线程安全,性能将受到很大影响.解决方案是用空间换时间,不用锁也能实现线程安全. 来看一个小例子,在线程内的set.get就是threadLocal 1 public class ConnThreadLocal { 2 3 public static ThreadLocal<String> th = new ThreadLocal<String>(); 4 5 public void setTh(String value

单例与多线程

一.饿汉模式 public class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){ } private static Singleton getInstance(){ return instance; } } 第一次加载类时就会创建Singleton 实例,所以是线程安全的.另一方面,如果这个Singleton 实例的创建非常消耗系统资源, 而应用始终都没有使用Singl

分享一个线程安全的单例模板类

单例模式应该说是最简单的设计模式了.在此分享一个线程安全的单例模板类. template <typename Type> class CSingleton { public: static Type* GetInstance() { // kBeingCreatedMarker用来表示单例实例正在创建过程中. // 此处初始化为1是因为操作系统不会分配地址为1的指针. static const volatile intptr_t kBeingCreatedMarker = 1; // 如果m_

C++实现一个线程安全的单例工厂

我们见到经常有人用 static 局部对象的方式实现了类似单例模式,最近发现一篇文章明确写明 编译器在处理  static局部变量的时候 并不是线程安全的 !!! http://blogs.msdn.com/b/oldnewthing/archive/2004/03/08/85901.aspx 于是实现了一个单例工厂  并且是线程安全的 #ifndef SINGLETONFACTORY_H #define SINGLETONFACTORY_H #include "windows.h"

java懒汉式单例遇到多线程

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能. 每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中.每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用.总之,选择单例模式就是为了避免不一致状态,避免政出多头. 1 public cl

单例类多线程

作为设计模式理论中的Helloworld,相信学习java语言的人,都应该听说过单例模式.单例模式作为对象的一种创建模式,它的作用是确保某一个类在整个系统中只有一个实例,而且自行实例化并向整个系统提供这个实例. 由此可见,单例模式具有以下的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一的实例. 单例类必须给所有其他对象提供这一实例. 由于Java语言的特点,使得单例模式在Java语言的实现上有自己的特点.这些特点主要表现在单例类如何将自己实例化. 饿汉式单例类 饿汉式单例类是在Ja

设计一个线程安全的单例(Singleton)模式

在设计单例模式的时候,虽然很容易设计出符合单例模式原则的类类型,但是考虑到垃圾回收机制以及线程安全性,需要我们思考的更多.有些设计虽然可以勉强满足项目要求,但是在进行多线程设计的时候.不考虑线程安全性,必然会给我们的程序设计带来隐患.此处,我们不介绍什么是单例模式,也不介绍如何设计简单的设计模式,因为你完全可以在书上或者在博客中找到.此处我们的目的就是设计一个使用的单例模式类.单例模式需要注意与思考的问题: (1)如何仅能实例化一个对象? (2)怎么样设计垃圾回收机制? (3)如何确保线程安全性

java单例 同步 多线程

get="_blank" href="http://www.csdn.net/tag/%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f">设计模式多线程javaclassthreadstring 单例模式的特点: 只创建一次 私有的属性 公有的访问方法 单例模式的分类: 懒汉(LazySingleton):默认不自动实例化,等到用的时候根据当前情况实例化,并且返回当前对象: 恶汉(EagerSingleton):在类第一次加载的时候强制

单例在多线程中的使用

一次执行  dispatch_once: 对应的代码只执行一次 , 并且它是线程安全的, 系统会自动这个函数加锁,保存同一时间只有一个线程去执行任务, 实现真正意义的一次性执行 什么时候需要用到一次性执行:  单例 单例: 就是在程序运行期间,只有一个实例化对象  ---- 举例:音乐播放器的App, 同时只能播放一首歌曲. 好处: 如果不使用同一个播放管理器对象, 那就播放下一首歌曲时, 先销毁上一个对象, 再创建一个新对象 这样做就比较消耗资源. 既然同一个时刻只能播放一首歌曲 ,所以我们只