• 架构师养成记--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){
     6         th.set(value);
     7     }
     8     public void getTh(){
     9         System.out.println(Thread.currentThread().getName() + ":" + this.th.get());
    10     }
    11     
    12     public static void main(String[] args) throws InterruptedException {
    13         
    14         final ConnThreadLocal ct = new ConnThreadLocal();
    15         Thread t1 = new Thread(new Runnable() {
    16             @Override
    17             public void run() {
    18                 ct.setTh("张三");
    19                 ct.getTh();
    20             }
    21         }, "t1");
    22         
    23         Thread t2 = new Thread(new Runnable() {
    24             @Override
    25             public void run() {
    26                 try {
    27                     Thread.sleep(1000);
    28                     ct.getTh();
    29                 } catch (InterruptedException e) {
    30                     e.printStackTrace();
    31                 }
    32             }
    33         }, "t2");
    34         
    35         t1.start();
    36         t2.start();
    37     }
    38     
    39 }
    View Code

    二、单例和多线程

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

    static inner class方式:

    1 public class InnerSingleton{
    2   private static class Singleton{
    3       private static Singleton single = new Singleton();
    4   }      
    5   public Singleton getInstance(){
    6       return Singleton.single;    
    7    }
    8 }    
    View Code

    double check instance 方式:

     1 public class DubbleSingleton {
     2 
     3     private static DubbleSingleton ds;
     4     
     5     public  static DubbleSingleton getDs(){
     6         if(ds == null){
     7             try {
     8                 //模拟初始化对象的准备时间...
     9                 Thread.sleep(3000);
    10             } catch (InterruptedException e) {
    11                 e.printStackTrace();
    12             }
    13             synchronized (DubbleSingleton.class) {
    14                 if(ds == null){
    15                     ds = new DubbleSingleton();
    16                 }
    17             }
    18         }
    19         return ds;
    20     }
    21     
    22     public static void main(String[] args) {
    23         Thread t1 = new Thread(new Runnable() {
    24             @Override
    25             public void run() {
    26                 System.out.println(DubbleSingleton.getDs().hashCode());
    27             }
    28         },"t1");
    29         Thread t2 = new Thread(new Runnable() {
    30             @Override
    31             public void run() {
    32                 System.out.println(DubbleSingleton.getDs().hashCode());
    33             }
    34         },"t2");
    35         Thread t3 = new Thread(new Runnable() {
    36             @Override
    37             public void run() {
    38                 System.out.println(DubbleSingleton.getDs().hashCode());
    39             }
    40         },"t3");
    41         
    42         t1.start();
    43         t2.start();
    44         t3.start();
    45     }
    46     
    47 }
    View Code
  • 相关阅读:
    国外程序猿整理的机器学习资源大全
    一个改动配置文件的linux shell script
    python高精度浮点型计算的诡异错误
    错误:'dict' object is not callable
    AssertionError while merging cells with xlwt (Python)
    Python => ValueError: unsupported format character 'Y' (0x59)
    [转]Python的3种格式化字符串方法
    python requirements使用方法
    conda虚拟环境实践
    迭代器中next()的用法
  • 原文地址:https://www.cnblogs.com/sigm/p/6147784.html
Copyright © 2020-2023  润新知