Is it safe to use an object in different threads, but NOT at the same time?

I read everywhere that if a field is used at the same time by different threads, some synchronization is required, and if it is used by only one thread, it is not needed. But what if it is used by different threads, but not at the same time? Take the following code:

Thing thing = new Thing(); Thread t1 = new Thread(new MyRunnable(thing)); Thread t2 = new Thread(new MyRunnable(thing)); t1.start(); t1.join();//Wait for t1 to finish t2.start(); 

MyRunnable:

 class MyRunnable implements Runnable { //skipped constructor and field "private final Thing thing" public void run() { thing.someUpdate(); } } 

It is safe? Any updates made by t1 to visible t2?

+5
source share
5 answers

In this case, the changes are visible, because Thread.join and Thread.start creates events - before the relationship between actions in both threads. See Memory Negotiation Errors :

  • When an operator calls Thread.start, every statement that has a happening - before a relationship with that statement will also have a - before a relationship with every statement executed by a new thread. The effect of the code that led to the creation of the new stream is visible to the new stream.

  • When the thread terminates and calls Thread.join in another return thread, then all the statements executed by the completed thread, a occurs before dealing with all the statements following the successful connection. The effects of the code in the stream are now visible to the stream that performed the connection.

If you did not use these methods in this order, the changes may not be available. Threads should not be started at the same time to cause a problem, because the values ​​may be cached in the stream or some optimization may occur, etc.

+9
source

I think this question is too abstract. The general answer to the question: "Are all changes made by t1 visible on t2?" Yes. "But they will only be visible because of how you start the threads. The threads in your example are not parallel. So, yes, in this example, the MyRunnable fields will be visible for both threads. But the MyRunnable class itself is not thread safe. If it is will be used with parallel threads, you are likely to get in trouble. It depends on the details of MyRunnable.someUpdate (). You should use the "volatile" keyword for your fields, classes "java.util.concurrent. * "Or any synchronization mechanisms, if necessary. Perhaps this documentation will help get you started: https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

+1
source

In your case, this is safe, since both threads are not working at the same time.

0
source

join() method is a lock method and waits for the thread to complete. t2 should see all t1 updates.

0
source

In this case, it is safe. Changes made by t1 to the object of the object will be visible to t2. If there was no t1.join (); the code would not be thread safe.

 t1.start(); t1.join();//Wait for t1 to finish t2.start(); 
0
source

Source: https://habr.com/ru/post/1245946/


All Articles