我有两个线程使用相同的Object obj
并且我已经阅读obj
Thread A
所做的每一项更改都会显示Thread B
由于之前发生的关系obj
我想要做的是反之,在Thread A
中更改Thread B
而ThreadLocal
无法看到,但我不知道如何做到这一点。
我尝试在Thread B
中创建run()
,在ThreadLocal.get()
方法中进行设置,并在obj
中使用Thread B
代替public class MyThreadLocal {
public static final ThreadLocal<Email> threadLocal = new ThreadLocal<Email>();
public static void set(Email email) {
threadLocal.set(email);
}
public static void remove() {
threadLocal.remove();
}
public static Email get() {
return threadLocal.get();
}
}
但它一直在阅读变化。
有谁知道如何实现这个目标?
提前致谢
编辑:(MVCE)
serviceEnvioTaskSpring.setThreadName(getIdInstanciaOrigen()); //serviceEnvioTaskSpring is an instance of a class which implements Runnable
//set some more class' attributes
serviceEnvioTaskSpring.setEmail(email); //email is the shared object
ExecutorService threadExecutor = Executors.newCachedThreadPool();
threadExecutor.execute(serviceEnvioTaskSpring);
threadExecutor.shutdown();
主线程
public void run() {
try {
//a few business logic lines
MyThreadLocal.set(email);
this.performTask();
} catch (Exception e) {
logger.error( "Error al lanzar thread asincrono: "+ e.getMessage()+" - "+e.getCause() );
e.printStackTrace();
}
}
public void performTask() {
//do stuff in a for loop accessing email with MyThreadLocal.get();
}
主题B
email
问题发生在我继续运行主线程时,因为下一步是刷新整个页面,因此 $.ajax(settings)
.success(function (response) {
flag = 1;
console.log(response);
})
.error(function(err) {
flag = -1; // End your while loop?
});
设置为新实例,这使我失去了MyThreadLocal的电子邮件信息
答案 0 :(得分:4)
我有两个线程使用相同的Object obj,并且我已经读过线程A在obj中所做的每个更改都会因为之前发生的关系而在线程B中可见。
这不正确。或者至少......它是不正确的,因为你写了 1 。
现实情况是发生 - 之前关系可确保更新可见。如果没有发生在之前的关系,则更改可能是可见的......或者它们可能不可见。
我想要做的是相反的,改变线程A中的obj而不是从线程B可见但我不知道如何做到这一点。
基本上,你不能保证它。如果两个线程正在查看同一个对象,那么就无法阻止一个线程看到另一个线程的更改。
使用线程局部变量并没有帮助。
如果您希望一个线程看不到另一个线程对对象所做的更改,那么您需要复制或克隆该对象并让两个线程使用不同的副本。
1 - (你所写的内容暗示A所做的更改始终对B是可见的,因为发生在之前的关系。但是那里不一定是发生在之前的关系!我会认为你可能没有意味着 ......但我不知道知道你并不是故意的,这就是我迂腐的原因。)