线程A执行:
class A{
public String value;
public void methodA(String value){ //lets say value="test"
this.value=value;
//some code
// Thread B interrupts
System.out.println(value); // prints "haha" but I want it to be "test"
}
}
线程B确实:
class B{
public void methodB(){
a.setValue("haha");
}
}
methodB和methodA是某些类型的侦听器方法,它们在单独的线程中执行。
只要methodA尚未完成,我怎样才能确保值不会改变?但我也希望“haha”之后被赋予价值。所以我希望B等到A完成methodA然后将“haha”分配给值。
答案 0 :(得分:1)
最简单的方法是在更改字段值的方法上使用'synchronized'关键字。
例如,我们有一个存储数据的类:
public class Data {
String value = "";
public synchronized void setValue(String val) {
this.value = val;
System.out.println(val);
}
}
然后Threads仅使用此方法更新值。当时只有一个线程可以执行此方法(无中断)。
如果你想在两种方法上传播它(就像我想的那样)。您可以使用两个选项。或者在两种方法上使用synchronized
或使用外部锁定对象。
如果你想确定,例如线程A必须首先执行,你可以使用CountDownLatch
对象,这将阻止其他线程,直到线程A不会减少锁存器。
有许多方法可以处理同步。您应该更准确地了解您想要实现的目标以及您想要处理的场景。例如 - a.setValue("haha")
是来自A类的方法吗?
我还建议查看有关并发性https://docs.oracle.com/javase/tutorial/essential/concurrency/的文档。
答案 1 :(得分:0)
如果您只想在调用methodB()
之前完成java.util.concurrent.CountDownLatch
,那么您应该从同一个线程调用这两个方法。一般来说,如果您希望程序按特定顺序执行某些操作,那么实现它的最佳方法是
在一个线程中完成所有事情。
另一方面,您可能希望两个线程在大多数情况下并行工作,但可能有一个特定点,即您不希望线程B通过,直到线程A到达那里。 Java标准库提供了可以使用的各种不同的同步对象。例如,CountDownLatch countDownLatch=new CountDownLatch(1);
threadA.start();
threadB.start();
。
初始化:
doSomeStuff();
methodA();
countDownLatch.countDown();
doSomeMoreStuff();
主题A:
doSomeOtherStuff();
countDownLatch.await();
methodB();
doSomeMoreOtherStuff();
ThreadB:
{{1}}
doSomeStuff()和doSomeOtherStuff()调用可以同时发生,并且doSomeMoreStuff()和doSomeMoreOtherStuff()调用可以同时发生,但在这种情况下,methodA()和methodB()将被序列化。