现在的位置: 首页 > 综合 > 正文

ThreadLocal的使用及实现

2013年12月13日 ⁄ 综合 ⁄ 共 4401字 ⁄ 字号 评论关闭

在java中,如果一个变量需要被多个线程访问,可以使用volatile来声明它为“易变的”。而假如一个变量要被持有它的某个线程独享,在java中,它可以使用java.lang.ThreadLocal类来实现线程本地存储的功能。这样,数据便只在同一个线程内可见和共享,因此,即便不同步也能保证线程之间不出现数据争用。

ThreadLocal使得各线程能够保持各自独立的一个对象,通过ThreadLocal.set()来设置对象的值,保存在每个线程自己都有的一个map对象当中,每个ThreadLocal对象会有一个线程范围内唯一hashcode作为key,ThreadLocal.get()内部通过这个key从map中取值,因此取出来的是各自自己线程中的对象,ThreadLocal实例事实上只是作为map的key来使用的。

一个ThreadLocal的例子:

 

Java代码  收藏代码
  1. package com.threadlocal.test;  
  2.   
  3. /** 
  4.  * @Author: chenkangxian 
  5.  * 
  6.  * @Annotation: 
  7.  * 
  8.  * @Date:2012-4-20 
  9.  *  
  10.  */  
  11. public class test {  
  12.   
  13.     class ConcurrentCount extends Thread{  
  14.           
  15.         ThreadLocal<Integer> count ;  
  16.           
  17.         public ConcurrentCount(ThreadLocal<Integer> count){  
  18.             this.count = count;  
  19.         }  
  20.   
  21.         @Override  
  22.         public void run() {  
  23.               
  24.             for(int i = 0; i < 10; i ++){  
  25.                   
  26.                 if(count.get() != null){  
  27.                     count.set(count.get() + 1);  
  28.                 }else{  
  29.                     count.set(0);  
  30.                 }  
  31.                   
  32.                 System.out.println("Thread: " + this.currentThread().getName() + ", count: " + count.get());  
  33.             }  
  34.               
  35.             return ;  
  36.         }  
  37.           
  38.     }  
  39.       
  40.     /** 
  41.      * Author: chenkangxian 
  42.      * 
  43.      * Last Modification Time: 2012-4-20 
  44.      * 
  45.      * @param args 
  46.      */  
  47.     public static void main(String[] args) {  
  48.   
  49.           
  50.         //所有线程均使用该变量,但是却不存在线程安全问题  
  51.         ThreadLocal<Integer> count = new ThreadLocal<Integer>();  
  52.           
  53.         test test = new test();  
  54.           
  55.         ConcurrentCount count1 = test.new ConcurrentCount(count);  
  56.         ConcurrentCount count2 = test.new ConcurrentCount(count);  
  57.         ConcurrentCount count3 = test.new ConcurrentCount(count);  
  58.         ConcurrentCount count4 = test.new ConcurrentCount(count);  
  59.           
  60.         count1.start();  
  61.         count2.start();  
  62.         count3.start();  
  63.         count4.start();  
  64.   
  65.     }  
  66.   
  67. }  

 

 

ThreadLocal使用归纳有两点:

1.每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。 
2.将一个共用的ThreadLocal实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象。

 

 

ThreadLocal实现的源代码:

 

Java代码  收藏代码
  1. /* 
  2.  * @(#)ThreadLocal.java 1.42 06/06/23 
  3.  * 
  4.  * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 
  5.  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 
  6.  */  
  7.   
  8. package java.lang;  
  9. import java.lang.ref.*;  
  10. import java.util.concurrent.atomic.AtomicInteger;  
  11.   
  12.        new ThreadLocal &lt; Integer > () { 
  13. public class ThreadLocal<T> {  
  14.  
  15.     private final int threadLocalHashCode = nextHashCode();  
  16.   
  17.     /** 
  18.      * The next hash code to be given out. Updated atomically. Starts at 
  19.      * zero. 
  20.      */  
  21.     private static AtomicInteger nextHashCode =   
  22.     new AtomicInteger();  
  23.   
  24.     /** 
  25.      * The difference between successively generated hash codes - turns 
  26.      * implicit sequential thread-local IDs into near-optimally spread 
  27.      * multiplicative hash values for power-of-two-sized tables. 
  28.      */  
  29.     private static final int HASH_INCREMENT = 0x61c88647;  
  30.   
  31.     /** 
  32.      * Returns the next hash code. 
  33.      */  
  34.     private static int nextHashCode() {  
  35.     return nextHashCode.getAndAdd(HASH_INCREMENT);   
  36.     }  
  37.   
  38.   
  39.      * @return the initial value for this thread-local 
  40.      */  
  41.     protected T initialValue() {  
  42.         return null;  
  43.     }  
  44.   
  45.     /** 
  46.      * Creates a thread local variable. 
  47.      */  
  48.     public ThreadLocal() {  
  49.     }  
  50.   
  51.    
  52.     public T get() {  
  53.         Thread t = Thread.currentThread();  
  54.         ThreadLocalMap map = getMap(t);  
  55.         if (map != null) {  
  56.             ThreadLocalMap.Entry e = map.getEntry(this);  
  57.             if (e != null)  
  58.                 return (T)e.value;  
  59.         }  
  60.         return setInitialValue();  
  61.     }  
  62.   
  63.     private T setInitialValue() {  
  64.         T value = initialValue();  
  65.         Thread t = Thread.currentThread();  
  66.         ThreadLocalMap map = getMap(t);  
  67.         if (map != null)  
  68.             map.set(this, value);  
  69.         else  
  70.             createMap(t, value);  
  71.         return value;  
  72.     }  
  73.     public void set(T value) {  
  74.         Thread t = Thread.currentThread();  
  75.         ThreadLocalMap map = getMap(t);  
  76.         if (map != null)  
  77.             map.set(this, value);  
  78.         else  
  79.             createMap(t, value);  
  80.     }  
  81.   
  82.      public void remove() {  
  83.          ThreadLocalMap m = getMap(Thread.currentThread());  
  84.          if (m != null

抱歉!评论已关闭.