ThreadLocal这么回事

 今天线程池实现,看到一个使用ThreadLocal的地方,研究了一下ThreadLocal这东西,发现很有意思。

从源码研究看ThreadLocal的实现原理吧

 

package com.sogou.game.cms.pool;

import org.apache.thrift.transport.TSocket;

public class ConnectionManager {
	ThreadLocal<TSocket> socketThreadSafe = new ThreadLocal<TSocket>();

	/** 连接提供池 */
	public ConnectionProvider connectionProvider;

	public ConnectionManager(){
		connectionProvider=new ConnectionProviderImpl();
	}
	/**
	* 取socket
	* @return TSocket
	*/
	public TSocket getSocket() {
		TSocket socket = null;
		try {
			socket = connectionProvider.getConnection();
			socketThreadSafe.set(socket);

			return socketThreadSafe.get();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			connectionProvider.returnCon(socket);
			socketThreadSafe.remove();
		}

		return socket;
	}

	public ConnectionProvider getConnectionProvider() {
		return connectionProvider;
	}

	public void setConnectionProvider(ConnectionProvider connectionProvider) {
		this.connectionProvider = connectionProvider;
	}

}
 

 

这段代码里面使用了ThreadLocal,ThreadLocal在使用时一般会声明为static变量,后面分析源码时候会说到为什么是static。

ThreadLocal

看一下ThreadLocal的get方法

 

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

 

 获取当前线程,然后将当前线程传入getMap()得到ThreadLocalMap

下面是ThreadLocalMap的实现方式,可以简单认为是一个map,key为ThreadLocal值,value为要set的值;

 

 

static class ThreadLocalMap {

        /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference<ThreadLocal> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }
}

 

 继续getMap方法

 

ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

 返回Thread t的threadLocals的值,那threadLocals为何物呢?

 

ThreadLocal.ThreadLocalMap threadLocals = null;

 转了一圈怎么又回来了

理一下思路

static ThreadLocal 在set的时候是set到Thread自有的ThreadLocalMap中,key为threadlocal变量

ThreadLocal的作用就了然了

在多线程,假设ThreadA、ThreadB,static的ThreadLocal是相同的,当ThreadA执行set方法是,是将相应的key、value set自己独有的ThreadLocalMap中,get方法的原理也同样。由于key不变,所以保证多线程在get、set时取到自身在set、get时值,这也是为什么ThreadLocal一般是static了。

 

 

 

 

你可能感兴趣的:(threadLocal)