Threadlocal

JDKAPI 解释: 

       该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其get或set方法)的每个线程都有自己的局部变量,它独立于 初始化变量的副本。ThreadLocal实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。 

资料查找总结: 

ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。  个人认为ThreadLocal 就是一种Map key-value 的实现思路。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本 。将每个线程作为key ,线程操作的数据作为value。每个线程可以独立修改自己的value ,而不影响其他线程对应的value。 

ThreadLocal方法详细信息 : 

initialValue 
protected T initialValue()返回此线程局部变量的当前线程的“初始值”。线程第一次使用 get() 方法访问变量时将调用此方法,但如果线程之前调用了 set(T) 方法,则不会对该线程再调用 initialValue 方法。通常,此方法对每个线程最多调用一次,但如果在调用 get() 后又调用了 remove(),则可能再次调用此方法。  
该实现返回 null;如果程序员希望线程局部变量具有 null 以外的值,则必须为 ThreadLocal 创建子类,并重写此方法。通常将使用匿名内部类完成此操作。  

返回: 
返回此线程局部变量的初始值 

get 
public T get()返回此线程局部变量的当前线程副本中的值。如果变量没有用于当前线程的值,则先将其初始化为调用 initialValue() 方法返回的值。  

返回: 
此线程局部变量的当前线程的值 

set 
public void set(T value)将此线程局部变量的当前线程副本中的值设置为指定值。大部分子类不需要重写此方法,它们只依靠 initialValue() 方法来设置线程局部变量的值。  

参数: 
value - 存储在此线程局部变量的当前线程副本中的值。 

remove 
public void remove()移除此线程局部变量当前线程的值。如果此线程局部变量随后被当前线程读取,且这期间当前线程没有设置其值,则将调用其 initialValue() 方法重新初始化其值。这将导致在当前线程多次调用 initialValue 方法

 

      threadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。 
Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。 
当然ThreadLocal并不能替代synchronized,它们处理不同的问题域。Synchronized用于实现同步机制,比ThreadLocal更加复杂。

demo
package com.candy.test;
 
public class SequenceNumber {
 
 
     private static ThreadLocal<Integer> local= new ThreadLocal<Integer>(){
         public Integer initialValue(){
             return 0 ;
         }
     };
 
     public int getNextNum(){
 
         local.set(local.get()+ 1 );
         return local.get();
 
     };
}
 
 
 
package com.candy.test;
 
public class ClientThread implements Runnable {
 
     private SequenceNumber sn;
 
     public ClientThread(SequenceNumber sn) {
 
         this .sn = sn;
 
     }
 
     public void run() {
         for ( int i = 0 ; i < 3 ; i++) {
             System.out.println( "[" +Thread.currentThread().getName()+ "]=" +sn.getNextNum());
         }
 
     }
 
}
 
 
 
 
 
package com.candy.test;
 
 
public class AppTest {
 
     public static void main(String[] args) {
 
//      ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
//      UserInfoService userInfoService =(UserInfoService) act.getBean("userinfoservice");
//      userInfoService.getUsername("s");
         SequenceNumber sn = new SequenceNumber();
         ClientThread c1= new ClientThread(sn);
         ClientThread c2= new ClientThread(sn);
         ClientThread c3= new ClientThread(sn);
 
         Thread t1= new Thread(c1);
         Thread t2= new Thread(c2);
         Thread t3= new Thread(c3);
         t1.start();
         t2.start();
         t3.start();
 
 
 
     }
}

你可能感兴趣的:(Threadlocal)