java threading lock变量正确

时间:2015-11-30 11:55:17

标签: java thread-safety synchronized

线程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”分配给值。

2 个答案:

答案 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()将被序列化。