Многопоточность Java без отношения "до и после"
У меня есть две темы, использующие один и тот же Object obj
и как я прочитал все изменения, сделанные в obj
от Thread A
будет виден для Thread B
из-за случившегося до отношений.
То, что я хочу сделать, это наоборот, изменение obj
в Thread A
не будучи видимым из Thread B
но я понятия не имею, как это сделать.
Я пытался создать ThreadLocal
в Thread B
, установив его в run()
метод и использование ThreadLocal.get()
вместо obj
в Thread B
но он продолжает читать изменения.
Кто-нибудь знает, как этого добиться?
заранее спасибо
РЕДАКТИРОВАТЬ: (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();
Нить Б
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
1 ответ
У меня есть два потока, использующих один и тот же объект obj, и, поскольку я прочитал каждое изменение, внесенное в obj потоком A, будет видно для потока B из-за отношения "до и после".
Это не правильно. Или, по крайней мере... это не правильно, как вы написали1.
Реальность такова, что отношения " до того" гарантируют, что обновления будут видны. Если отношения " до и после" не существует, изменения могут быть видны... или они НЕ видны.
То, что я хочу сделать, это наоборот, изменить obj в потоке A, не будучи видимым из потока B, но я понятия не имею, как это сделать.
По сути, вы не можете гарантировать это. Если два потока смотрят на один и тот же объект, то невозможно остановить один поток, чтобы увидеть изменения другого.
Использование локальных переменных потока не помогает.
Если вы хотите, чтобы один поток не видел изменений, внесенных в объект другим потоком, то вам необходимо скопировать или клонировать объект, и эти два потока будут использовать разные копии.
1 - (То, что вы написали, подразумевает, что изменение, сделанное A, всегда будет видимым для B, потому что есть отношения " до того, как это произошло". Но это не обязательно отношения " до того, как произошло"! Я признаю, что вы, возможно, не имели в виду, что... но я не знаю, что ты не имел в виду это, поэтому я педантичен.)