编程语言
首页 > 编程语言> > Java多线程,无事前发生关系

Java多线程,无事前发生关系

作者:互联网

我有两个使用相同对象obj的线程,并且由于读取了事前关系,因此我已经读过线程A在obj中所做的每个更改对于线程B都是可见的.

我想做的是相反的,在线程A中更改obj,而从线程B中看不到它,但是我不知道如何执行此操作.

我尝试在线程B中创建一个ThreadLocal,在run()方法中进行设置,并在线程B中使用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();      
}

当我继续运行主线程时会发生此问题,因为其下一步是刷新整个页面,因此电子邮件设置为新实例,这使我丢失了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.

现实是,事前发生的关系保证了更新将是可见的.如果没有以前发生的关系,则更改可能是可见的……或者可能不可见.

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可见,因为存在事前发生的关系.但是不一定有事前发生的关系!我会同意,您可能并不意味着…但是我不知道你不是这个意思,这就是为什么我要脚.

标签:multithreading,happens-before,java
来源: https://codeday.me/bug/20191025/1930754.html