概述
2019独角兽企业重金招聘Python工程师标准>>>
单从字面翻译更应该是本地化线程,然后却是线程局部变量(ThreadLocalVariable)不是更合适吗?
ThreadLocal到底是用来干什么的喃?当然是保存线程私有的数据啊,所以通常变量是被修饰为private的。与局部变量不同,通常是被定义为全部变量,然后它为所有线程都维护一份私有数据,具体实现方式就是为每一个线程维护一个用Entity数组实现的Map
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();
}
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;
}
}
/**
* The initial capacity -- MUST be a power of two.
*/
private static final int INITIAL_CAPACITY = 16;
/**
* The table, resized as necessary.
* table.length MUST always be a power of two.
*/
private Entry[] table;
}
线程局部变量和线程共享数据区别在于一个用空间换时间,一个用时间换空间。后者用同步进行排队访问,而前者因为是独自维护的,不涉及同步问题
举例:
package com.jv.java8.datetime;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.junit.Test;
public class TestDateTime {
@Test
public void test1() {
ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
//SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return sdf.get().parse("2018228");
}
};
ExecutorService pool = Executors.newFixedThreadPool(5);
List<Future<Date>> results = new ArrayList<>();
for(int i=0;i<10;i++) {
results.add(pool.submit(task));
}
results.stream().map(x->{
try {
return x.get();
} catch (Exception e) {
}
return null;
}).forEach(System.out::println);
}
}
对于代码中使用的Lambda表达式可以Java-Lambda表达式
对于设计的局部变量类型需要注意伪共享问题,可以参考伪共享
转载于:https://my.oschina.net/u/3049601/blog/1553215
最后
以上就是暴躁小蝴蝶为你收集整理的ThreadLocal(线程局部变量)的全部内容,希望文章能够帮你解决ThreadLocal(线程局部变量)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复