Java 没有 happens-before 关系的多线程

Java multithreading without happens-before relationship

我有两个使用相同 Object obj 的线程,正如我所读,Thread Aobj 中所做的每项更改都将对 Thread B 可见,因为发生了 -关系之前。

我想做的恰恰相反,在 Thread A 中更改 objThread B 不可见,但我不知道该怎么做。

我尝试在 Thread B 中创建一个 ThreadLocal,在 run() 方法中设置它,并在 [=17] 中使用 ThreadLocal.get() 而不是 obj =] 但它一直在读取更改。

有人知道如何实现吗?

提前致谢

编辑: (MVCE)

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();
    }
}

主线程

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(); 

线程 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 的电子邮件信息

I have two threads using the same Object obj and as I have read every change made in obj by Thread A will be visible for Thread B due to happens-before relationship.

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

现实情况是 happens-before 关系保证更新可见。如果没有 happens-before 关系,那么更改可能是可见的......或者它们可能是不可见的。

What I want to do is the opposite, changing obj in Thread A without being visible from Thread B but I have no clue about how to do that.

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

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

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


1 -(您所写的内容意味着 A 所做的更改将 始终 对 B 可见,因为 发生了- before 关系。但不一定存在 happens-before 关系!我承认你可能没有 meant ...但我不知道你不是那个意思,这就是我迂腐的原因。)