Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

do I need a lock?

MyObject myObj ...

public void updateObj(){
     MyObject newObj = getNewMyObject();
     myObj = newObj;
}

public int getSomething(){
     //O(n^2) operation performed in getSomething method
     int something = myObj.getSomething();
     return something;
}

Suppose the main thread periodically calls updateObj() and a child thread calling getSomething() method pretty often.

Do I need a lock (or declare methods as synchronized) before myObj = newObj; and int something = myObj.getSomething();

Someone argued I don't need a lock here because in Java, assignment operations (e.g myObj = newObj;) is atomic. But what I don't get it is that myObj.getSomething(); this is not an atomic operation but its O(n^2) so I think a locking is still needed. Is this correct?

like image 966
user800799 Avatar asked Apr 15 '14 06:04

user800799


2 Answers

You need to declare myObject volatile, otherwise getSomething() method may not see updated object. Other than that I cannot see any synchronization issues in the above code

like image 114
Evgeniy Dorofeev Avatar answered Oct 14 '22 01:10

Evgeniy Dorofeev


Yes, you must synchronize your access to the shared variable properly. According to the Java Memory Model, your code doesn't guarantee happens-before relationship between the read and the write in all possible executions.

Proper synchronization doesn't always mean using locks; In your case, declaring myObj as volatile can do the job (assuming that you don't mutate it after construction).

like image 2
Eyal Schneider Avatar answered Oct 14 '22 00:10

Eyal Schneider