Java多线程没有发生之前的关系

时间:2017-09-06 11:47:53

标签: java multithreading happens-before

我有两个线程使用相同的Object obj并且我已经阅读obj Thread A所做的每一项更改都会显示Thread B由于之前发生的关系obj

我想要做的是反之,在Thread A中更改Thread BThreadLocal无法看到,但我不知道如何做到这一点。

我尝试在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的电子邮件信息

1 个答案:

答案 0 :(得分:4)

  

我有两个线程使用相同的Object obj,并且我已经读过线程A在obj中所做的每个更改都会因为之前发生的关系而在线程B中可见。

这不正确。或者至少......它是不正确的,因为你写了 1

现实情况是发生 - 之前关系可确保更新可见。如果没有发生在之前的关系,则更改可能是可见的......或者它们可能不可见。

  

我想要做的是相反的,改变线程A中的obj而不是从线程B可见但我不知道如何做到这一点。

基本上,你不能保证它。如果两个线程正在查看同一个对象,那么就无法阻止一个线程看到另一个线程的更改。

使用线程局部变量并没有帮助。

如果您希望一个线程看不到另一个线程对对象所做的更改,那么您需要复制或克隆该对象并让两个线程使用不同的副本。

1 - (你所写的内容暗示A所做的更改始终对B是可见的,因为发生在之前的关系。但是那里不一定是发生在之前的关系!我会认为你可能没有意味着 ......但我不知道知道你并不是故意的,这就是我迂腐的原因。)