欢迎使用CSDN-markdown编辑器

来源:互联网 发布:建材价格查询软件 编辑:程序博客网 时间:2024/05/18 13:05

ThreadLocal在并发中的使用

Thread类中有这么一句 ThreadLocal.ThreadLocalMap threadLocals = null;

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) {
@SuppressWarnings(“unchecked”)
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
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);
}

而在并发编程中仅仅使用Thread是会出现问题的,多次执行如下代码:
package org.spring_test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;

public class AppTest implements Runnable{
// Runnable r1 = () -> { System.out.println(this); };
// 加了synchronized 的 Integer
final AtomicInteger number = new AtomicInteger();
volatile boolean bol = false;
//news是我自己随便建的
news n ;
ThreadLocal count = new ThreadLocal();
@Override
public void run() {
//news是我自己随便建的
n = new news();
// setcount();
// System.out.println(Thread.currentThread().getName()+” : “+count.get());
System.out.println(Thread.currentThread().getName()+” : “+n);
synchronized (this) {
try {
if (!bol) {
bol = true;
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(“并发数量为” + number.intValue());
}
}
@Test
public void test() {
//线程池模拟高并发
ExecutorService pool = Executors. newCachedThreadPool();
AppTest test = new AppTest( );
for (int i=0;i<10;i++) {
pool.execute(test); Thread
}
}
public void setcount(){
count.set(n);
}

}
多次执行结果会出现如下结果:
pool-1-thread-2 : org.spring_test.news@497c84d9
pool-1-thread-1 : org.spring_test.news@497c84d9
pool-1-thread-3 : org.spring_test.news@6f0f4e10
pool-1-thread-4 : org.spring_test.news@324bc6ce
pool-1-thread-5 : org.spring_test.news@70a0b3f3
pool-1-thread-6 : org.spring_test.news@3ce56f17
pool-1-thread-7 : org.spring_test.news@508f404b
pool-1-thread-8 : org.spring_test.news@70170fb6
pool-1-thread-9 : org.spring_test.news@497a030d
pool-1-thread-10 : org.spring_test.news@734a16c4

注意看thread-1和thread-2出现了相同的引用,这个是我反复测试执行出的结果,多运行几次就出现了,这个问题怎么办?
上边代码改一下,调用threadlocal试试:
setcount();
System.out.println(Thread.currentThread().getName()+” : “+count.get());
//System.out.println(Thread.currentThread().getName()+” : “+n);

反复测试,未出现上边重复引用对象的情况,问题得到解决!