ThreadLocal的使用

/ 多线程 / 没有评论 / 320浏览

我们知道在Java中用static关键字可以实现变量的共享,那么在多线程环境中可以用ThreadLocal让每一个线程都有自己的私用数据。首先我们先看一下共享变量的实例。

/**
* 用户登录
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:35
* @since 1.0.0
*/
public class Userinfo extends Thread {

public volatile static int count;

@Override
public synchronized void run() {
count++;
System.out.println(String.format("count: %s\tthread: %s", count, Thread.currentThread().getName()));
}
}
/**
* 测试类
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:49
* @since 1.0.0
*/
public class RequestRun {
public static void main(String[] args) throws InterruptedException {
Userinfo userinfo = new Userinfo();
Userinfo userinfo2 = new Userinfo();
userinfo.start();
userinfo2.start();
}
}
count: 1	thread: Thread-0
count: 2	thread: Thread-1

我们看因为count变量是共享变量,所以在两个线程中操作的是同一个count实例变量,所以输出的时候第二个线程输出2。下面我们创建一个ThreadLocal变量来看一下它的效果。

/**
* 用户登录
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:35
* @since 1.0.0
*/
public class Userinfo extends Thread {

public volatile static int count;
public static ThreadLocal localCount = new ThreadLocal();

private synchronized static void count() {
if (localCount.get() == null) {
localCount.set(1);
} else {
int tempCount = (int) localCount.get();
tempCount++;
localCount.set(tempCount);
}
count++;
System.out.println(String.format("count: %s\tthread: %s", count, Thread.currentThread().getName()));
System.out.println(String.format("localCount: %s\tthread: %s", localCount.get(), Thread.currentThread().getName()));
}

@Override
public void run() {
count();
}
}
count: 1	thread: Thread-0
localCount: 1	thread: Thread-0
count: 2	thread: Thread-1
localCount: 1	thread: Thread-1

我们看到localCount的输出都是1,这是由ThreadLocal的特性决定的。用ThreadLocal修饰的数据,每一个线程都是独立的一份,所以线程1在向ThreadLocal数据set()的时候,线程二的ThreadLocal数据还是为空。所以每次操作都是自己的那个,所以输出都是1。在实际多线程的开发中,常用ThreadLocal解决同一份数据处理不同业务的情况。因为它们彼此之间不会互相影响。