直接贴代码了
package test; public class TestThreadLocal { public static void main(String[] args) { /*ExecutorService exce = Executors.newCachedThreadPool(); for(int i=0;i<10;i++){ exce.execute(new Thread(new TestThread(),"this is thread:"+i)); } exce.shutdown(); } */ //一个公共的对象 TestI testI = new TestI(); //创建一个ThreadLocal来维护这个对象 LocalObject localObject = new LocalObject(); localObject.addTestI(testI); // System.out.println(localObject.getTestI().getI()); for(int i=0;i<10 ;i++){ new Thread(new TestThread(localObject),"this is thread:"+i).start(); } } } class LocalObject{ //创建一个ThreadLocal 用来维护对象TestI private ThreadLocal<TestI> testIocal = new ThreadLocal<TestI>(); public void addTestI(TestI testI){ testIocal.set(testI); } public TestI getTestI(){ return testIocal.get(); } public void doSomeThing(){ getTestI().setI(); } } class TestThread implements Runnable{ private LocalObject localObject ; public TestThread(LocalObject localObject){ this.localObject = localObject; } private int i=10; @Override public void run() { while(this.localObject.getTestI().getI()>0){ this.localObject.doSomeThing(); i--; if(this.localObject.getTestI().getI()!=i){ System.out.println(Thread.currentThread().getName()+"not matched"); } // System.out.println(Thread.currentThread().getName()+"::"+LocalObject.getTestI().getI()); } } } class TestI { private int i=10; public void setI(){ i--; } public int getI(){ return i; } }
报错是Exception in thread "this is thread:1" java.lang.NullPointerException
at test.TestThread.run(TestThreadLocal.java:75)
就是run方法里面找不到对象,但是我通过构造方法注入了一个对象了呀。怎么回事 搞了2天了。。。
你没有理解ThreadLocal的含义....
ThreadLocal是针对本线程进行设置和读取, 你下面这个是在main所在线程里设置的...
TestI testI = new TestI();
//创建一个ThreadLocal来维护这个对象
LocalObject localObject = new LocalObject();
localObject.addTestI(testI);
当然只能从main所在的线程里读取了.
你启动的TestThread线程里, 根本就没有设置过, 怎么可能读取到呢?
没仔细看你的代码,只是提醒一下ThreadLocal 其实只是创建一个id,真正你往ThreadLocal里面set object,这个object其实是存在当前线程的某个map里面,你get的时候也是根据这个id从当前线程里面拿东西。不同的线程是不能共享你放到threadlocal里面的同一对象的,即你一个线程put,另外一个线程get是拿不到东西的。
[code="java"]
public class Test2 {
public static void main(String[] args) {
/*ExecutorService exce = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
exce.execute(new Thread(new TestThread(),"this is thread:"+i));
}
exce.shutdown();
}
*/
//一个公共的对象
for(int i=0;i<10 ;i++){
new Thread(new TestThread(),"this is thread:"+i).start();
}
}
}
class LocalObject{
//创建一个ThreadLocal 用来维护对象TestI
public ThreadLocal<TestI> testIocal = new ThreadLocal<TestI>();
public void addTestI(TestI testI){
testIocal.set(testI);
}
public TestI getTestI(){
return testIocal.get();
}
public void doSomeThing(){
getTestI().setI();
}
}
class TestThread implements Runnable{
private int i=10;
@Override
public void run() {
TestI testI = new TestI();
//创建一个ThreadLocal来维护这个对象
LocalObject localObject = new LocalObject();
localObject.addTestI(testI);
while(localObject.getTestI().getI()>0){
localObject.doSomeThing();
i--;
if(localObject.getTestI().getI()!=i){
System.out.println(Thread.currentThread().getName()+"not matched");
}
// System.out.println(Thread.currentThread().getName()+"::"+LocalObject.getTestI().getI());
}
}
}
class TestI {
public int i=10;
public void setI(){
this.i--;
}
public int getI(){
return this.i;
}
}
[/code]
ThreadLocal 必須在線程裡set他的get才會抓得到,先set在丟進線程是get不到值的。
threadlocal里面存的东西,就是自己线程的一个副本。用以隔离线程之间的相互影响,这么传是传不进去的。