What object do I synchronize on in Scala? - java

In C# it's pretty straightforward:
class Class1{
private static readonly object locker = new object();
void Method1(){
lock(locker) { .... }
}
}
And I definitely should not make a synchronization on this because it might lead to a deadlock. Likewise, in Scala I saw examples and couldn't get the idea of what is the basic principle of synchronization and object (field) I should use to make a synchronization:
#1
def add(user: User) {
// tokenizeName was measured to be the most expensive operation.
val tokens = tokenizeName(user.name)
tokens.foreach { term =>
userMap.synchronized {
add(term, user)
}
}
}
#2
class Person(var name: String) {
def set(changedName: String) {
this.synchronized {
name = changedName
}
}
}
#3 and so on...
Would you mind making it clear for me?

In Scala it's even more straightforward to get the same behavior (I'm assuming you want to lock on the contained object for some reason e.g. more fine-grained control than locking the whole instance of that class):
class Class1 {
private object Locker
def method1 { Locker.synchronized { ... } }
}
But you should rarely control things this way. In particular, it won't prevent deadlocks in either C# or Scala without a lot of attention to what goes into ....
You should at least use the concurrency tools in java.util.concurrent, and you may want to look into futures or actors.

Having a lock on object in Scala is the same as having the lock on static field/class in Java, which is basically one of 'hardest' locks. It will block operations not on instance of class, but on class itself in scope of class loader. You should think carefully when introducing locks like this. It doesn't protect you from a deadlock due to incorrect ordering of acquired locks, but instead leads to blocking threads if ones are working with different instances of a class, and may not interfere at all.
having a lock on 'this' or some class (not object) field (mutex) is more relaxed way of synchronization, you should use it for managing access not to class - but to particular instance of this class.
look at actors in akka, they rock and eliminate many of problems with synchronization.
side-note: making synchronization on 'this' doesn't imply deadlocks.

If the premise is that you want to avoid locking on this because another thread with third party code can lock on the same object, then Scala offers one more level of visibility private[this].
class C {
private[this] val lock = new Object()
def method1(): Unit = lock.synchronized {
println("method1")
}
}
Here actually no other object other than a particular instance of C can access lock. Even other instances from the same class cannot access lock.

Related

What are the impacts of using Object.class lock in synchronized block?

I am trying to synchronize read write operations on xml file from multiple methods in multiple classes. To achieve this, I am synchronizing this operations by using class level lock.
Code sample:
Test1.java:
public class Test1 {
public void method1() {
synchronized(CommonUtility.class) {
SomeObject someObject = testDAO.readSomething();
.
.
.
testDAO.writeSomething(someObject);
}
}
}
Test2.java
public class Test2 {
public void method2() {
synchronized(CommonUtility.class) {
SomeObject someObject = testDAO.readSomething();
.
.
.
testDAO.writeSomething(someObject);
}
}
}
To achieve this class level lock, consider following sample code:
synchronized(CommonUtility.class) {
.
.
.
}
What are the impacts of using Object.class instead of CommonUtility.class, like:
synchronized(Object.class) {
.
.
.
}
I think both approaches aren't ideal.
First of all, this here suggests:
You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class.
In other words: when you use synchronized(CommonUtility.class) you implicitly get "synchronized" with all static synchronized methods within CommonUtility. And worse: imagine that class has no such methods today. But next week, someone adds such a static synchronized method in that utility class, assuming that only calls to that method go through that monitor. Worst case, that could lead to some ugly (runtime only) surprises.
Then: going for even broader scope (by using Object.class) makes things worse.
My answer: avoid using class objects in the first place.
IMO, the idea of "class level" lock and "object level" lock is distracting. There is only one underlying synchronization mechanism in Java: synchronized (o) { ... } where o can be any Java object (Note that in Java MyClass.class is an object.)
When you write,
synchronized SomeType foobar(...) { ... }
That's really just a shortcut way of using an instance as the lock object that protects its own member variables.
SomeType foobar(...) {
synchronized (this) {
...
}
}
Same goes for so-called "class level" locking: It's just a shorthand way of using the class itself as the lock object that protects its own static members.
Speaking of which...
Good practice keeps the lock object near the data that it protects (for some definition of "near"). If the data are private, then the lock object ought to be private. If the data are members of some instance, then the lock object ought to be members of the same instance, etc.
Object.class isn't particularly "near" anything. It will work as well as any other object, but using it makes your code harder to understand, because the reader will spend time wondering what motivated you to choose Object.class, and wondering whether your choice was based on a misunderstanding.
My own preference, for protecting instance members, looks like this:
class MyClass {
private final Object lock = new Object();
private SomeType someVariableThatNeedsProtection = ...;
private SomeOtherType someOtherVariableThatAlsoNeedsProtection...;
...
public ... foobar(...) {
synchronized(lock) {
...
}
}
}
And, If I need to protect static members:
...
private static final Object lock = new Object();
...
The lock variable is private, just like the data it protects. Nobody who wants to understand your code will need to spend any time searching for anything else that is protected by the same lock object because they know it can't be accessed from outside of the MyClass methods.
The lock variable also is final. That will save readers from having to examine your code to make sure that it's always the same object that gets used as the lock. (Hint: if you think you need to be able to assign the lock variable, then you are either doing something that's sophisticated beyond the comfort level of many programmers, or you are making a bad mistake.)
I am trying to synchronize read write operations on XML file from multiple methods in multiple classes. To achieve this, I am synchronizing this operation by using class level lock.
That is not a good idea. You should have a single class (maybe XmlHelper) which manages the XML file and does the locking. XmlHelper would be used in the multiple methods in multiple classes and would control the locking on the file instead of multiple classes having to worry about it. That's much better object design.
Maybe something like:
public class XmlHelper {
public XmlHelper(File xmlFile) {
public synchronized SomeObject readSomething() { ... }
public synchronized void writeSomething(SomeObject someObject) { ... }
}
Then your Test1 and Test2 classes must share the same instance of the XmlHelper class so their locks will block each other. Instance level locks aren't always a great idea again because locks should be as fine-grained as possible, but it is fine in your application since the XmlHelper is designed for multiple classes to lock their IO operations.
What are the impacts of using Object.class instead of CommonUtility.class, like:
As others have mentioned, locking on the class is the same as calling a synchronized static method. This pattern should be used very sparingly since the lock is so coarse grained. What if your program needed to read/write to 2 XML files at the same time? Your class level lock would cause IO operations to the 2 files block each other -- not optimal.
If you locked on Object.class then any other class which happens to be doing the same lock will block your threads unnecessarily. God help you.
A race condition is getting hit. For example: thread1 reads file contents and updates read contents. Before thread1 writes back to file, thread2 reads content. Then thread1 writes updated contents to file. And at last thread2 writes content to file. This is leading to contents loss,
There are a couple of ways of doing this. You could have some sort of update method on your XmlHelper class:
public synchronized void updateObject(...) {
SomeObjecto obj = readSomething();
// adjust object here based on the arguments
writeSomething(obj);
}
If each of the threads need to do their own updating then they will need to lock externally on the same object. I recommend locking on the shared instance of the XmlHelper.
synchronized (xmlHelper) {
...
}
The locking on the class object will work but it is far to big a hammer to be recommended. Again, if you have 2 instances of the XmlHelper working on 2 different files, you would not want IO operations on 2 different files to block each other.

How to use synchronized blocks across classes?

I want to know how to use synchronized blocks across classes. What I mean is, I want to have synchronized blocks in more than one class but they're all synchronizing on the same object. The only way that I've thought of how to do this is like this:
//class 1
public static Object obj = new Object();
someMethod(){
synchronized(obj){
//code
}
}
//class 2
someMethod(){
synchronized(firstClass.obj){
//code
}
}
In this example I created an arbitrary Object to synchronize on in the first class, and in the second class also synchronized on it by statically referring to it. However, this seems like bad coding to me.
Is there a better way to achieve this?
Having a static object that is used as a lock typically is not desirable because only one thread at a time in the whole application can make progress. When you have multiple classes all sharing the same lock that's even worse, you can end up with a program that has little to no actual concurrency.
The reason Java has intrinsic locks on every object is so that objects can use synchronization to protect their own data. Threads call methods on the object, if the object needs to be protected from concurrent changes then you can add the synchronized keyword to the object's methods so that each calling thread must acquire the lock on that object before it can execute a method on it. That way calls to unrelated objects don't require the same lock and you have a better chance of having code actually run concurrently.
Locking shouldn't necessarily be your first go-to technique for concurrency. Actually there are a number of techniques you can use. In order of descending preference:
1) eliminate mutable state wherever possible; immutable objects and stateless functions are ideal because there's no state to protect and no locking required.
2) use thread-confinement where you can; if you can limit state to a single thread then you can avoid data races and memory visibility issues, and minimize the amount of locking.
3) use concurrency libraries and frameworks in preference to rolling your own objects with locking. Get acquainted with the classes in java.util.concurrent. These are a lot better written than anything an application developer can manage to throw together.
Once you've done as much as you can with 1, 2, and 3 above, then you can think about using locking (where locking includes options like ReentrantLock as well as intrinsic locking). Associating the lock with the object being protected minimizes the scope of the lock so that a thread doesn't hold the lock longer than it needs to.
Also if the locks aren't on the data being locked then if at some point you decide to use different locks rather than having everything lock on the same thing, then avoiding deadlocks may be challenging. Locking on the data structures that need protecting makes the locking behavior easier to reason about.
Advice to avoid intrinsic locks altogether may be premature optimization. First make sure you're locking on the right things no more than necessary.
OPTION 1:
More simple way would be to create a separate object (singleton) using enum or static inner class. Then use it to lock in both the classes, it looks elegant:
// use any singleton object, at it's simplest can use any unique string in double quotes
public enum LockObj {
INSTANCE;
}
public class Class1 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
OPTION:2
you can use any string as JVM makes sure it's only present once per JVM. Uniqueness is to make sure no-other lock is present on this string. Don't use this option at all, this is just to clarify the concept.
public class Class1 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
Your code seems valid to me, even if it does not look that nice. But please make your Object you are synchronizing on final.
However there could be some considerations depending on your actual context.
In any way should clearly state out in the Javadocs what you want to archive.
Another approach is to sync on FirstClass e.g.
synchronized (FirstClass.class) {
// do what you have to do
}
However every synchronized method in FirstClass is identical to the synchronized block above. With other words, they are also synchronized on the same object. - Depending on the context it may be better.
Under other circumstances, maybe you'd like to prefer some BlockingQueue implementation if it comes down that you want to synchronize on db access or similar.
I think what you want to do is this. You have two worker classes that perform some operations on the same context object. Then you want to lock both of the worker classes on the context object.Then the following code will work for you.
public class Worker1 {
private final Context context;
public Worker1(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Worker2 {
private final Context context;
public Worker2(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Context {
public static void main(String[] args) {
Context context = new Context();
Worker1 worker1 = new Worker1(context);
Worker2 worker2 = new Worker2(context);
worker1.someMethod();
worker2.someMethod();
}
}
I think you are going the wrong way, using synchronized blocks at all. Since Java 1.5 there is the package java.util.concurrent which gives you high level control over synchronization issues.
There is for example the Semaphore class, which provides does some base work where you need only simple synchronization:
Semaphore s = new Semaphore(1);
s.acquire();
try {
// critical section
} finally {
s.release();
}
even this simple class gives you a lot more than synchronized, for example the possibility of a tryAcquire() which will immediately return whether or not a lock was obtained and leaves to you the option to do non-critical work until the lock becomes available.
Using these classes also makes it clearer, what prupose your objects have. While a generic monitor object might be misunderstood, a Semaphore is by default something associated with threading.
If you peek further into the concurrent-package, you will find more specific synchronisation-classes like the ReentrantReadWriteLock which allows to define, that there might be many concurrent read-operations, while only write-ops are actually synchronized against other read/writes. You will find a Phaser which allows you to synchronize threads such that specific tasks will be performed synchronously (sort of the opposite of synchornized) and also lots of data structures which might make synchronization unnecessary at all in certain situations.
All-in-all: Don't use plain synchronized at all unless you know exactly why or you are stuck with Java 1.4. It is hard to read and understand and most probably you are implementing at least parts of the higher functions of Semaphore or Lock.
For your scenario, I can suggest you to write a Helper class which returns the monitor object via specific method. Method name itself define the logical name of the lock object which helps your code readability.
public class LockingSupport {
private static final LockingSupport INSTANCE = new LockingSupport();
private Object printLock = new Object();
// you may have different lock
private Object galaxyLock = new Object();
public static LockingSupport get() {
return INSTANCE;
}
public Object getPrintLock() {
return printLock;
}
public Object getGalaxyLock() {
return galaxyLock;
}
}
In your methods where you want to enforce the synchronization, you may ask the support to return the appropriate lock object as shown below.
public static void unsafeOperation() {
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
public void unsafeOperation2() { //notice static modifier does not matter
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
Below are few advantages:
By having this approach, you may use the method references to find all places where the shared lock is being used.
You may write the advanced logic to return the different lock object(e.g. based on caller's class package to return same lock object for all classes of one package but different lock object for classes of other package etc.)
You can gradually upgrade the Lock implementation to use java.util.concurrent.locks.LockAPIs. as shown below
e.g. (changing lock object type will not break existing code, thought it is not good idea to use Lock object as synchronized( lock) )
public static void unsafeOperation2() {
Lock lock = LockingSupport.get().getGalaxyLock();
lock.lock();
try {
// perform your operation
} finally {
lock.unlock();
}
}
Hopes it helps.
First of all, here are the issues with your current approach:
The lock object is not called lock or similar. (Yes ... a nitpick)
The variable is not final. If something accidentally (or deliberately) changes obj, your synchronization will break.
The variable is public. That means other code could cause problems by acquiring the lock.
I imagine that some of these effects are at the root of your critique: "this seems like bad coding to me".
To my mind, there are two fundamental problems here:
You have a leaky abstraction. Publishing the lock object outside of "class 1" in any way (as a public or package private variable OR via a getter) is exposing the locking mechanism. That should be avoided.
Using a single "global" lock means that you have a concurrency bottleneck.
The first problem can be addressed by abstracting out the locking. For example:
someMethod() {
Class1.doWithLock(() -> { /* code */ });
}
where doWithLock() is a static method that takes a Runnable or Callable or similar, and then runs it with an appropriate lock. The implementation of doWithLock() can use its own private static final Object lock ... or some other locking mechanism according to its specification.
The second problem is harder. Getting rid of a "global lock" typically requires either a re-think of the application architecture, or changing to a different data structures that don't require an external lock.

In Java, synchronized block can synchronize on any object reference?

I was wondering if there is a situation where this statement will be true and needed. All the examples I have seen only synchronize on the "this" reference. Can someone tell me how a block of code in one object can be synchronized on any other reference apart from this ?
Yes the statement is true.
There are several reasons why one would want NOT to use an intrinsic monitor (synchronized(this)) - one of these reasons is that it can create liveness issues - in the code below, B uses an instance of A as a lock, maybe to control access to that variable. If another thread uses that same instance of A and tries to run a.methodA(), it will be blocked until methodB() is over.
So using an intrinsic monitor exposes the synchronization policy and can lead to subtle bugs and performance issues.
public class A {
public synchronized void methodA() {}
}
public class B {
A a = new A();
public void methodB() {
synchronized(a) {
// do something a little long
}
}
public A getA() {return a;}
}
If A had used an internal monitor that problem would not be possible.
public class A {
private final Object lock = new Object();
public void methodA() {
synchronized(lock) {}
}
}
Another scenario where using ad hoc monitors makes sense is when a class contains 2 (or more) unrelated objects, that both need to be accessed in a synchronized manner. Using 2 monitors instead of one reduces contention as the 2 objects can now be accessed concurrently.
public class SyncTest{
private Object obj = new Object();
public void func1() {
synchronized(obj) {
obj.something();
}
}
Yes it can be done.
The synchronize block will use that object as a lock, rather than the whole class. People that use synchronized(this) { } put an exclusive lock on the whole object, which might be what you want. However, you might have something like a persister, which is the only thing that needs to be synchronized. synchronized(persister) { }, would provide a less granular way of doing this.
In Java, you can use synchronized constructs to create instrinsic locks on any object reference, yes. Read the relevant Java Tutorial.
The immediate example of not using synchronized with this is when synchronizing on the Class object, which is how static synchronized methods work. In reality, there are plenty of valid uses. You may want to avoid using synchronized (this) in favor of an internal implementation lock as otherwise you are setting a restriction that you use the lock internally, which other code you're not aware of might violate.
You should know, however, that often times you can replace synchronized usage with a ReentrantLock. You can read more about this in my post here.

Can a shared resource safely be used as the lock for a synchrnized block?

I often find myself with code like
private static final MyType sharedResource = MyType();
private static final Object lock = new Object();
...
synchronized(lock)
{
//do stuff with sharedResource
}
Is this really neccessary or could sharedResource be used as the lock itself like
private static final MyType sharedResource = MyType();
...
synchronized(sharedResource)
{
//do stuff with sharedResource
}
Note: synchronized blocks shown in the examples would live within methods doing work and are not methods themselves or synchronized methods.
EDIT: A very good point has been pointed out in some of the answers that if we are dealing with multiple shared resources that the first "Object" technique is far safer.
WARNING The fact that sharedResource is static is important! If it is static then synchronized methods or synchronized blocks locking on this won't work. The lock object must also be static.
Pros and cons of both
First option pros: Allows locking on concept, not on Objects. If you had to lock on multiple resources for a single action (which is usually not advised, but sometimes necessary) you could do this with much less worry about race conditions.
cons: The object could still be modified, so you need to ensure access to the object is restricted to methods that abide by the external lock.
Second option pros: Lock on the object should prevent others from modifying it (although you should double check the exact symantics.) EDIT: Has the same con as above - if the methods aren't synchronized internally, you could still run into methods that don't abide by the contract.
cons: You block access to all methods, even those unrelated to what you're trying to operate, which could cause slowdowns and possibly deadlock. You could easily make the case, however, that if that's the case your Object is doing too much work and should be broken up.
EDIT: Allow me to clarify part 2 here (the case to break up MyType into MyFoo and MyBar is open for debate...)
class MyType {
Foo foo;
Bar bar;
void doFoo() { foo.do(); }
void doBar() { bar.do(); }
}
class MyActions {
MyType thing;
void lotsOfFoo() {
// blocks bar :-(
synchronized(thing) { thing.doFoo(); }
}
void lotsOfBar() {
// blocks foo :-(
synchronized(thing) { thing.doBar(); }
}
}
Personally, I use option 1 much more often (that's why I'm unsure about that part in option 2).
The only problem I see, with using sharedResource as a lock if MyType has methods defined as synchronized itself. In this case, some strange behaviour my occur that was not intended by the developers of MyType. (See glowcoder's comment for an example.)
Otherwise it should be fine, however if you do only need one lock anyway, then just synchronize on this instead of introducing an additional dummy object.
Btw, did you itentionally make your lock object static? Because this means that all instance lock on the same monitor, i.e. they can block each other, which may not bee the behaviour you intended.
Yes, you can absolutely do that.
In fact it improves clarity and reduces clutter.
If I remembered right, synchronized is a monitor, it grants that only one thread can access that object at any given time in the same JVM. So I think you are only accessing shardResouce, synchronizing on the shardResouce is sufficient.
Personally, I don't usually synchronize on an arbitrary lock. That is, I'd usually do something along the lines of your second approach:
private static final MyType sharedResource = MyType();
...
synchronized(sharedResource) {
//do stuff with sharedResource
}
Of course, before running synchronized code, the lock for the target object must be obtained. Often, I take the locking "down" a step further, so to speak. Meaning, I would synchronize on a method within "sharedResource." As in:
public class MyType {
public void synchronized doWork() {
}
}
But when it comes to this kind of thing, it's hard to make generalizations because there are exceptions to every rule. In the end, your overall architecture requirements will dictate where your locking should occur. For me, most often, I find myself synchronizing the top-level method that accesses the shared resources and it is thereby more rare to lock on an object who does nothing more than serve as a lock.
EDIT: minor grammar fixes

What Cases Require Synchronized Method Access in Java?

In what cases is it necessary to synchronize access to instance members?
I understand that access to static members of a class always needs to be synchronized- because they are shared across all object instances of the class.
My question is when would I be incorrect if I do not synchronize instance members?
for example if my class is
public class MyClass {
private int instanceVar = 0;
public setInstanceVar()
{
instanceVar++;
}
public getInstanceVar()
{
return instanceVar;
}
}
in what cases (of usage of the class MyClass) would I need to have methods:
public synchronized setInstanceVar() and
public synchronized getInstanceVar() ?
Thanks in advance for your answers.
The synchronized modifier is really a bad idea and should be avoided at all costs. I think it is commendable that Sun tried to make locking a little easier to acheive, but synchronized just causes more trouble than it is worth.
The issue is that a synchronized method is actually just syntax sugar for getting the lock on this and holding it for the duration of the method. Thus, public synchronized void setInstanceVar() would be equivalent to something like this:
public void setInstanceVar() {
synchronized(this) {
instanceVar++;
}
}
This is bad for two reasons:
All synchronized methods within the same class use the exact same lock, which reduces throughput
Anyone can get access to the lock, including members of other classes.
There is nothing to prevent me from doing something like this in another class:
MyClass c = new MyClass();
synchronized(c) {
...
}
Within that synchronized block, I am holding the lock which is required by all synchronized methods within MyClass. This further reduces throughput and dramatically increases the chances of a deadlock.
A better approach is to have a dedicated lock object and to use the synchronized(...) block directly:
public class MyClass {
private int instanceVar;
private final Object lock = new Object(); // must be final!
public void setInstanceVar() {
synchronized(lock) {
instanceVar++;
}
}
}
Alternatively, you can use the java.util.concurrent.Lock interface and the java.util.concurrent.locks.ReentrantLock implementation to achieve basically the same result (in fact, it is the same on Java 6).
It depends on whether you want your class to be thread-safe. Most classes shouldn't be thread-safe (for simplicity) in which case you don't need synchronization. If you need it to be thread-safe, you should synchronize access or make the variable volatile. (It avoids other threads getting "stale" data.)
If you want to make this class thread safe I would declare instanceVar as volatile to make sure you get always the most updated value from memory and also I would make the setInstanceVar() synchronized because in the JVM an increment is not an atomic operation.
private volatile int instanceVar =0;
public synchronized setInstanceVar() { instanceVar++;
}
. Roughly, the answer is "it depends". Synchronizing your setter and getter here would only have the intended purpose of guaranteeing that multiple threads couldn't read variables between each others increment operations:
synchronized increment()
{
i++
}
synchronized get()
{
return i;
}
but that wouldn't really even work here, because to insure that your caller thread got the same value it incremented, you'd have to guarantee that you're atomically incrementing and then retrieving, which you're not doing here - i.e you'd have to do something like
synchronized int {
increment
return get()
}
Basically, synchronization is usefull for defining which operations need to be guaranteed to run threadsafe (inotherwords, you can't create a situation where a separate thread undermines your operation and makes your class behave illogically, or undermines what you expect the state of the data to be). It's actually a bigger topic than can be addressed here.
This book Java Concurrency in Practice is excellent, and certainly much more reliable than me.
To simply put it, you use synchronized when you have mutliple threads accessing the same method of the same instance which will change the state of the object/or application.
It is meant as a simple way to prevent race conditions between threads, and really you should only use it when you are planning on having concurrent threads accessing the same instance, such as a global object.
Now when you are reading the state of an instance of a object with concurrent threads, you may want to look into the the java.util.concurrent.locks.ReentrantReadWriteLock -- which in theory allows many threads to read at a time, but only one thread is allowed to write. So in the getter and setting method example that everyone seems to be giving, you could do the following:
public class MyClass{
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private int myValue = 0;
public void setValue(){
rwl.writeLock().lock();
myValue++;
rwl.writeLock().unlock();
}
public int getValue(){
rwl.readLock.lock();
int result = myValue;
rwl.readLock.unlock();
return result;
}
}
In Java, operations on ints are atomic so no, in this case you don't need to synchronize if all you're doing is 1 write and 1 read at a time.
If these were longs or doubles, you do need to synchronize because it's possible for part of the long/double to be updated, then have another thread read, then finally the other part of the long/double updated.

Categories