简体   繁体   中英

Use of synchronized on a block with instance variable

When i synchronize a block by an instance variable, it's variable can be just accessed (not edited) by other thread?

Example:

If a thread invokes setValue , the value gets lock. But if another thread invokes getValue during the lock, I don't know if this call goes to wait mode.

setValue(Integer newValue){
    synchronized (this.value){
        this.value = newValue;
    }
}

getValue(){
     return this.value;
}

When you are synchronizing on some object, it doesn't mean that this object is "locked" - it means that you acquired so called "intrinsic lock" associated with object (each object have one).

When some synchornization block is guarded by some object, it basically means that you will need to acquire intrinsic lock associated with that object in order to enter that block. When you are leaving synchronized block - you will also release lock.

Similar with synchronized methods - in that case "this" reference is used to guard method.

So "value" of object that is used for guarding synchronized block is not locked when some thread is inside synchronized block.

You can test it in easy way with something like this:

public class Test {

    Counter lockObject = new Counter();

    public static void main(String[] args) {
        new Test().go();
    }

    private void go() {
        new Thread(() -> {
            synchronized (lockObject) {
                while(true) {
                    System.out.println("Inside thread");
                }
            }
        }).start();

        while(true) {
            lockObject.inc();
            System.out.println(String.format("Accessing lock object: %d", lockObject.get()));
        }
    }
}

class Counter {
    int i = 0;
    public void inc() {
        i++;
    }
    public int get() {
        return i;
    }
}

Here thread is forever inside synchronized block guarded by "lockObject" but stil main thread can interact with it.

I would like that many threads access my map but synchronous by key... And all threads access any value by key passed

You could use ConcurrentHashMap .

Reading operations are cheap and not blocking thanks to a lock performed only on related key.

1) You are not compelled to synchronize the map when you do a get() from the map if you deem that a not updated reading is not a problem.
Which seems to be your use case.

2) If as in your example the value associated to the key in the map must reflect the exact value, you could synchronize the setValue() method to ensure that concurrent calls are well taken into consideration in the map value.

Be aware, the setValue() method should be synchronized only if the code executed inside it modifies the map according to the current map state.
Otherwise you don't need to synchronize it.

For example :

public class ExampleClass{

  private Map<Character, Integer> map = new ConcurrentHashMap<>();

  void synchronized setValue(String key, Integer newValue){ 
        // some processings ...            
        this.map.put(key, newValue);       
  }

  Integer getValue(String key){
     return map.get(key);
  }
}

When i synchronize a block by an instance variable...

You can't synchronize on a variable , you can only synchronize on an object . Your code does this:

synchronized (lockObject) {
    ...
}

That is not synchronizing on the variable named lockObject ; Your code is synchronizing on the new Counter() instance to which the lockObject variable refers.

...it's variable can be just accessed...?

The synchronized block does not prevent other threads from modifying the lockObject variable, and it does not prevent other threads from modifying the Counter instance. The only thing that the synchronized block prevents is, it prevents other threads from synchronizing on the same object at the same time.

If you want to prevent two threads from using the Counter at the same time, then its up to you to wrap a synchronized(lockObject) block around every place where your code uses it.

You could use ConcurrentHashMap.

I gona sugest this too.

Complementing with this link, where have a good explanation and other type of Map.

HashMap vs ConcurrentHashMap vs SynchronizedMap

Cheers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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