ThreadLocal学习笔记

Posted 等待戈多儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreadLocal学习笔记相关的知识,希望对你有一定的参考价值。

可参考《实战Java高并发程序设计》4.3

ThreadLocal是一个线程的局部变量,只有当前线程可以访问的数据。所以是线程安全的。

为每一个线程分配不同的对象,需要在应用层面保证。ThreadLocal只是起到了简单容器的作用。如果在应用上为每一个线程分配了相同的对象,ThreadLocal也不能保证线程安全。

/**
 *ThreadLocal简单使用
 */
public class TestTheadLocal 
	static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();

	public static class ParseDate implements Runnable 
		int i = 0;

		public ParseDate(int i) 
			this.i = i;
		

		@Override
		public void run() 
			if (tl.get() == null) 
				tl.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
			
			try 
				Date t = tl.get().parse("2016-06-29" + i % 60);
				System.out.println(i + ":" + t);
			 catch (ParseException e) 
				e.printStackTrace();
			
		

	



使用ThreadLocal为每一个线程都产生一个SimpleDateFormt对象实例。

实现原理(Jdk1.8的源码):其内部数据结构可以理解为一个HashMap,用户存储线程引用

set

 public void set(T value) 
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    

get

    public T get() 
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) 
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) 
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            
        
        return setInitialValue();
    


remove:及时回收对象,也可将tl=null

  /**
         * Remove the entry for key.
         */
        private void remove(ThreadLocal<?> key) 
            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);
            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) 
                if (e.get() == key) 
                    e.clear();
                    expungeStaleEntry(i);
                    return;
                
            
        

如果对象对于竞争的处理容易引起性能损失,应考虑使用ThreadLocal为每个线程分配单独的对象。典型案例就是多线程环境下产生随机数。


以上是关于ThreadLocal学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

ThreadLocal学习笔记

ThreadLocal学习笔记

ThreadLocal学习笔记

ThreadLocal学习笔记

Python学习笔记(二十九)ThreadLocal

Java学习笔记--ThreadLocal