简体   繁体   English

java线程锁定变量正确

[英]java threading lock variable properly

Thread A does: 线程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"
    }
}

Thread B does: 线程B执行:

class B{
    public void methodB(){
        a.setValue("haha");  
    }
}

methodB and methodA are some kinds of listener methods, which are executed in separate Threads. methodB和methodA是某些侦听器方法,它们在单独的线程中执行。

How can I make sure that value does not change, as long as methodA has not finished? 只要methodA还没有完成,如何确保值不变? But I want also that "haha" is assigned to value afterwards. 但我也希望事后将“ haha​​”分配给价值。 So I want B to wait till A has finished methodA and then assign "haha" to value. 因此,我希望B等待A完成方法A,然后将“ haha​​”分配给值。

The easiest way is to use 'synchronized' keyword on method that change the value of a field. 最简单的方法是在更改字段值的方法上使用“ synchronized”关键字。

For example we have class that stores the data: 例如,我们有存储数据的类:

public class Data {
   String value = "";
   public synchronized void setValue(String val) {
      this.value = val;
      System.out.println(val);
   }
}

And then Threads only use this method to update the value. 然后线程仅使用此方法来更新值。 Only one thread at the time can execute this method (no interrupts). 当时只有一个线程可以执行此方法(无中断)。

If you want to propagate this on two methods (like I suppose is the case). 如果您想在两种方法上传播它(就像我想的那样)。 You can use two options. 您可以使用两个选项。 Or use synchronized on both methods or use external lock object. 或在两种方法上都使用synchronized ,或使用外部锁对象。

If you want to be sure, that for example thread A has to be first to execute, you can use CountDownLatch object, which will stop other threads until thread A won't decrement the latch. 如果您想确保例如必须首先执行线程A,则可以使用CountDownLatch对象,该对象将停止其他线程,直到线程A不会减少锁存器为止。

There are many ways to handle synchronization. 有许多处理同步的方法。 You should be more precise to what you want to achieve and what kind of scenario you want to handle. 您应该对要实现的目标以及要处理的场景更加精确。 Like for example - Is a.setValue("haha") a method from class A? 例如a.setValue("haha")是A类的方法吗?

I would also recommend to look at documentation about concurrency https://docs.oracle.com/javase/tutorial/essential/concurrency/ . 我还建议您查看有关并发的文档https://docs.oracle.com/javase/tutorial/essential/concurrency/

If you just want methodA() to complete before methodB() is called, then you should call both methods from the same thread. 如果你只是想methodA()之前完成methodB()被调用时,那么你应该调用在同一个线程两种方法。 In general, if you want your program to do certain things in a certain order, the best way to accomplish it is to do all of the things in a single thread. 通常,如果希望程序按特定顺序执行某些操作,则最好的方法是在单个线程中完成所有操作。

On the other hand, you might want both threads to work in parallel most of the time, but there might be one particular point that you don't want thread B to pass until thread A gets there. 另一方面,您可能希望两个线程在大多数时间都并行工作,但是有一个特定的问题,您不希望线程B在线程A到达那里之前通过。 The Java standard library provides a variety of different synchronization objects that you could use. Java标准库提供了可以使用的各种不同的同步对象。 Eg, java.util.concurrent.CountDownLatch . 例如, java.util.concurrent.CountDownLatch

Initialization: 初始化:

CountDownLatch countDownLatch=new CountDownLatch(1);
threadA.start();
threadB.start();

Thread A: 线程A:

doSomeStuff();
methodA();
countDownLatch.countDown();
doSomeMoreStuff();

ThreadB: ThreadB:

doSomeOtherStuff();
countDownLatch.await();
methodB();
doSomeMoreOtherStuff();

The doSomeStuff() and doSomeOtherStuff() calls could happen concurrently, and the doSomeMoreStuff() and doSomeMoreOtherStuff() calls could happen concurrently, but the methodA() and methodB() would be serialized in this case. doSomeStuff()和doSomeOtherStuff()调用可以同时发生,而doSomeMoreStuff()和doSomeMoreOtherStuff()调用可以同时发生,但是在这种情况下,methodA()和methodB()将被序列化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM