如何在java中结合thread和threadlocal
我有一些方法声明如下:如何在java中结合thread和threadlocal,java,Java,我有一些方法声明如下: Thread thread = null; thread = new Thread(new Runnable() { public void run(){ ThreadContext context = new ThreadContext(); Collection<Result> result = context.get().search();//(2) resultsTemp.pu
Thread thread = null;
thread = new Thread(new Runnable() {
public void run(){
ThreadContext context = new ThreadContext();
Collection<Result> result = context.get().search();//(2)
resultsTemp.put("File", result);
}
});
thread.start();
该类声明使用ThreadLocal
从容器中获取Service
组件
public class ThreadContext {
private Connector connector;
private static ThreadLocal threadLocal = new ThreadLocal() {
@Override
protected Connector initialValue() {
Service service =
(Service) Container.getComponentInstanceOfType(Service.class);
Connector connector = service.getConnector();
return connector;
}
};
public static Connector get() {
return Connector threadLocal.get();
}
}
连接器属于中产阶级
public class Connector {
public Collection<Result> search() {
User user = ConversationUser.getCurrent()
}
}
然后,我编写了一个线程来执行以下操作:
Thread thread = null;
thread = new Thread(new Runnable() {
public void run(){
ThreadContext context = new ThreadContext();
Collection<Result> result = context.get().search();//(2)
resultsTemp.put("File", result);
}
});
thread.start();
Thread-Thread=null;
线程=新线程(新可运行(){
公开募捐{
ThreadContext=新的ThreadContext();
集合结果=context.get().search();/(2)
resultsTemp.put(“文件”,结果);
}
});
thread.start();
此线程正常工作,但在第(2)行发生NullPointerException
。
正如我所研究的,该方法在第(1)行返回null
我真的很困惑。我不明白为什么会发生这个问题。请对此进行一些澄清,谢谢。您正在初始化ConversationUser.current
到new ThreadLocal()
,而无需匿名扩展它以覆盖initialValue()
,就像您对ThreadContext.ThreadLocal所做的那样。因此,当第一次调用get
时,没有任何东西可以告诉它如何填充自身。由于没有代码调用set
来手动填充它,get
返回null
有关更多信息和有用示例,请参阅javadocs。我做了一些测试,问题是因为私有静态ThreadLocal
变量,我不知道为什么,但这并没有将对象链接到ThreadLocal
,似乎没有创建对象。我需要更多的时间来调查
无论如何,我为您提供了两种解决方案来解决此问题:
将该类创建为单例
public class ConversationUser extends ThreadLocal<ConversationUser>{
private static ThreadLocal<ConversationUser> current= null;
@Override
protected ConversationUser initialValue() {
return new ConversationUser();
}
public static ConversationUser getCurrent() {
if (current == null) {
current = new ConversationUser();
}
return current.get();
}
}
//用法newconversationuser().get()代码>
我试图回答你的问题,但我发现它太令人困惑了。您的示例中存在多个编译错误,而且似乎不完整。执行顺序似乎与您所描述的不同,因为search
调用getCurrent
。我想我会取消删除它,因为人们都在重复我的话。@fmodos是的,当我对这个问题有疑问时,我只是简单地删除了它。但这似乎是有用的信息,即使问题并不完全清楚。抱歉给你带来困惑。没问题,不管怎样,这是正确的答案。。。他从未设置threadlocal的实例。首先,我猜这个问题来自thread和threadlocal。我认为解决方案是使用synchronized for方法get。但这似乎不好。然而,当前变量已经在容器中的某个地方初始化。证据是,如果我正确地使用http请求调用,它会正常工作,不会发生异常,但线程不会。@fmodos你明白我的问题吗?
public class ConversationUser extends ThreadLocal<ConversationUser>{
@Override
protected ConversationUser initialValue() {
return new ConversationUser();
}
}