我正在使用ThreadLocal变量(通过Clojure的变量,但以下内容对于ThreadLocalJava中的普通变量是相同的)并且经常遇到这样的问题:我无法确定某个代码路径是在同一个线程上还是在另一个线程.对于我控制下的代码,这显然不是一个大问题,但对于多态第三方代码,有时甚至没有办法静态地确定是否可以安全地假设单线程执行.
我倾向于认为这是ThreadLocals 的固有问题,但我想听听一些如何以安全的方式使用它们的建议.
据我所知,ThreadLocal变量为每个线程维护一个单独的变量副本.保持多个副本的此变量本质上是一个共享变量.那么说变量值可以有多个副本是什么意思呢?如何保持一致性,以使副本的值不会失去同步?
java multithreading thread-safety thread-local java.util.concurrent
我试图通过线程执行在 run 方法中打印线程局部变量,但它显然为空。请查找代码获取信息---
public class EvenAndOdd implements Runnable{
public EvenAndOdd() {
}
public static void setThreadContext(){
threadLocal.set(3);
eventhreadLocal.set(2);
}
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
private static ThreadLocal<Integer> eventhreadLocal = new ThreadLocal<Integer>();
@Override
public void run() {
System.out.println(threadLocal.get());
System.out.println(eventhreadLocal.get());
}
}
Run Code Online (Sandbox Code Playgroud)
// 现在是用于创建线程并调用 run 方法的类
public class PrintNumber {
public static void main(String[] args) {
EvenAndOdd evenAndOdd =new EvenAndOdd();
EvenAndOdd.setThreadContext();
Thread printThread = new Thread(evenAndOdd);
printThread.start();
}
}
Run Code Online (Sandbox Code Playgroud)
问题陈述 --- 线程的执行给了我 null 而不是 2 和 3
我想知道当我将 threadlocal.set() 设置为 32 个元素的集合时,它是如何没有存储数据的。ThreadLocal.get() 总是返回 null;并且对应的 FutureTask 对象有一个结果属性 = NullPointerException。知道为什么 ThreadLocal 无法存储集合项吗?
public class MyCallable<T> implements Callable<Collection<T>> {
public MyCallable( Collection<T> items ){
tLocal = new ThreadLocal<Collection<T>>();
tLocal.set( items ); //SETS NULL ALTHOUGH the PARAMETER CONTAINS 32 ITEMS
}
@Override
@SuppressWarnings("unchecked")
public Collection<T> call() throws Exception {
synchronized( lock ){
ArrayList<T> _items = new ArrayList<T>();
ArrayList<T> _e = ( ArrayList<T> ) tLocal.get(); //RETURNS NULL
for( T item : _e ){
_items = getPValue( item ));
}
return _items ; …Run Code Online (Sandbox Code Playgroud) 以下类显示了与实际用例类似的内容.它始终为同一个线程返回相同的实例.
public class LookingForName {
private static final ThreadLocal<Something> threadLocal =
new ThreadLocal<Something>(){
@Override
protected Something initialValue() {
return getSomethingSpecial(); // not relevant
}
};
/**
* @return always the same instance of "Something" for the current thread.
*/
public static Something getInstance() {
return threadLocal.get();
}
}
Run Code Online (Sandbox Code Playgroud)
你怎么称呼它?它是"工厂"吗?"价值持有者"?"ThreadLocalStore"?
java design-patterns naming-conventions thread-local factory-pattern
我有一个类MyThread,它实现了Callable <String>.该类有一个构造函数,它接受像blockqueue和其他参数.在我的主类中,我使用新的阻塞队列和其他参数来实例化此类MyThread.此外,我维护两个映射,一个用MyThread参考保持一个唯一参数作为键,另一个用同一个唯一键保持阻塞队列引用.
在此过程中,我从hashmap获取此阻塞队列,添加我的自定义消息并获取相应的MyThread实例并提交到ThreadPoolTaskExecutor(Spring版本).
据我所知,每个线程都应该获得自己的值副本(如阻塞队列等),因为我在构造过程中传递它们,稍后使用ThreadPoolTaskExecutor.submit(myThreadObj)创建一个线程.我只是想知道是否有人可以确认这是否正确或者我是否需要在这种情况下使用ThreadLocal.到目前为止测试,我没有遇到问题,但后来我还没有进行负载测试.
提前致谢.
我有一个Vaadin应用程序,当你同时运行两个应用程序实例时,我会遇到一些奇怪的行为(一个在FF中,另一个在IE中).我已经删除了大多数静态对象(这些导致应用程序在与另一个打开的应用程序并行使用时完全重新加载),现在我可以正常地与UI进行交互,而无需完全重置.但是,我现在注意到我在两个接口中只获得了一个用户的数据.我假设这是由我用来管理一些数据缓存和SOAP连接的单例对象引起的.我想知道它是单独的模式本身导致奇怪的输出还是它只是我保持的静态实例对象?
我尝试将ThreadLocal与我的单例一起使用,但是当我尝试在我的单例函数中使用它们时,我的所有变量都是null.目前我的单身人士包含了这个,这可能非常糟糕,因为它不起作用.
private static ThreadLocal<SoapClient> instance = new ThreadLocal<SoapClient>();
public static synchronized SoapClient getInstance(){
if (instance.get() == null) {
instance.set(new SoapClient());
}
return instance.get();
}
Run Code Online (Sandbox Code Playgroud)
我选择了一个单例对象,所以我总是可以访问我的应用程序实例中的缓存数据和我的用户的soap连接,而我能想到的另一种方法就是在某个地方有一个静态对象,但是静态关键字似乎首先是我所有问题的原因.有什么方法可以解决这个问题还是有其他原因导致它?
/*我们使用Aspect在一些现有应用程序上执行AOP,我们还使用threadlocal来存储GUId.我们正在使用@Around注释.在事务开始时,我们使用initialValue()方法在事务中设置GUID.
问题就像我们所知,当我们使用threadlocal时,我们也应该注意从threadlocal中删除数据,否则它可能导致我的内存执行.如果我在最后一个方面删除它,它会破坏代码并更改UUID值.
请建议我们如何在没有outofmemory的情况下实现它.
代码: - */
@Aspect
public class DemoAspect {
@Pointcut("execution(* *.*(..)) ")
public void logging() {}
private static ThreadLocal<String> id = new ThreadLocal<String>() {
@Override
protected String initialValue(){
return UUID.randomUUID().toString();
}
};
@Around("logging()")
public Object tracing(ProceedingJoinPoint thisJoinPoint) throws Throwable {
String methodSignature=thisJoinPoint.getSignature().toString();
if(id.get().toString()==null || id.get().toString().length()==0)
id.set(UUID.randomUUID().toString());
System.out.println("Entering into "+methodSignature);
Object ret = thisJoinPoint.proceed();
System.out.println(id.get().toString());
System.out.println("Exiting into "+methodSignature);
//id.remove();
return ret;
}
}
Run Code Online (Sandbox Code Playgroud) 如何从当前线程获取Thread-local的值?我试图从当前线程获取线程本地的值,但在网上找不到任何帮助。