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

Posted 司广孟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构师养成记--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

 

以上是关于架构师养成记--6.单例和多线程ThreadLocal的主要内容,如果未能解决你的问题,请参考以下文章

架构师养成记--线程基础

单例和多线程

线程学习--单例和多线程ThreadLocal

架构师养成记--3.synchronized细节问题

架构师养成记--15.Disruptor并发框架

架构师养成记--2脏读