Java多线程没有发生在关系之前
我有两个线程使用相同的Java多线程没有发生在关系之前,java,multithreading,happens-before,Java,Multithreading,Happens Before,我有两个线程使用相同的对象obj,正如我所读到的线程A在对象obj中所做的每一个更改都将在线程B中可见,因为发生在关系之前 我想做的恰恰相反,在线程A中更改obj,而不在线程B中可见,但我不知道如何做 我曾尝试在线程B中创建线程本地,在run()方法中设置它,并使用ThreadLocal.get()而不是线程B中的obj,但它一直在读取更改 有人知道如何做到这一点吗 提前谢谢 编辑:(MVCE) 线程B public void run() { try { //a few
对象obj
,正如我所读到的线程A
在对象obj
中所做的每一个更改都将在线程B
中可见,因为发生在关系之前
我想做的恰恰相反,在线程A
中更改obj
,而不在线程B
中可见,但我不知道如何做
我曾尝试在线程B
中创建线程本地
,在run()
方法中设置它,并使用ThreadLocal.get()
而不是线程B
中的obj
,但它一直在读取更改
有人知道如何做到这一点吗
提前谢谢
编辑:(MVCE)
线程B
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();
}
问题发生在我继续运行主线程时,因为它的下一步是刷新整个页面,因此email
被设置为一个新实例,这会使我丢失MyThreadLocal的电子邮件信息
我有两个线程使用同一个对象obj,正如我读到的,线程A在obj中所做的每一个更改对于线程B都是可见的,这是因为关系发生在before之前
那是不对的。或者至少。。。它不像你写的那样正确
现实情况是,在关系保证更新是可见的之前,就发生了冲突。如果没有发生在关系之前,那么更改可能是可见的。。。或者它们可能不可见
我想做的是相反的,在线程A中更改obj而不从线程B中可见,但我不知道如何做
基本上,你不能保证。如果两个线程正在查看同一个对象,则无法阻止一个线程看到另一个线程的更改
使用线程局部变量没有帮助
如果希望一个线程看不到另一个线程对对象所做的更改,则需要复制或克隆该对象,并让两个线程使用不同的副本
1-(你所写的意味着a所做的改变对B来说总是可见的,因为有一个发生在关系之前。但不一定有一个发生在关系之前!我承认你可能不是那个意思……但我不知道你不是那个意思,这就是为什么我这么迂腐。)请提供一个。因此,两个不同的线程需要两个单独的对象。或者,为什么您希望拥有一个共享对象,但另一个线程看不到更改?之前发生的事件与此无关。您基本上是从不同的位置修改相同的对象/引用threads@ZaidAmir不是真的。
ThreadLocal
通常用于为每个Thread
提供其自身的某种类型的实例,即防止共享数据。但是如果没有MCVE,我们就帮不上忙了。@Persixty在这里,很抱歉没有在第一时间发布它,我试图做更多的理论问题
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();
}