Skip to main content

说说并发编程 ThreadLocal

类ThreadLocal 提供线程局部变量。这些局部变量不同于正常的变量,每个线程都有自己独立初始化的副本,可以通过threadLocal的set/get方法去改变它的。一般ThreadLocal 常用在类变量上。比如DateFormat类不是线程安全的,没有必要所有的方法都加上同步,这是利用ThreadLocal就可以达到效果。

创建ThreadLocal
[java]
private ThreadLocal myThreadLocal = new ThreadLocal();
[/java]

访问ThreadLocal
[java]
//设置变量
myThreadLocal.set("A thread local value");
//读取local变量
String threadLocalValue = (String) myThreadLocal.get();
[/java]

初始化ThreadLocal 变量

[java]
private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
@Override protected String initialValue() {
return "This is the initial value";
}
};
[/java]

例子
[java]
package com.learn.core.ch02;

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadId {

// Atomic integer containing the next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);

// Thread local variable containing each thread’s ID
private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() {

@Override
protected Integer initialValue() {
return nextId.getAndIncrement();
}
};

// Returns the current thread’s unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}

public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(new MyRunnable()).start();
}
}

public static class MyRunnable implements Runnable {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(threadId.get());
}

}
}

}
[/java]

总结:以下2中情况,可以考虑使用

  • 当每个线程仅仅想拥有自己的一些变量,不想所有的线程共享
  • 一些非线程安全的类变量或者工具类,为了保证线程安全,可以通过ThreadLocal作为线程局部变量达到线程安全的效果