Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronizing on an object in Java

I am looking for something akin to this syntax even though it doesn't exist.

I want to have a method act on a collection, and for the lifetime of the method, ensure that the collection isn't messed with.

So that could look like:

private void synchronized(collectionX) doSomethingWithCollectionX() {
    // do something with collection x here, method acquires and releases lock on
    // collectionX automatically before and after the method is called
}

but instead, I am afraid the only way to do this would be:

private void doSomethingWithTheCollectionX(List<?> collectionX) {
    synchronized(collectionX) {
        // do something with collection x here
    }
}

Is that the best way to do it?

like image 967
Alexander Mills Avatar asked Jan 14 '15 21:01

Alexander Mills


2 Answers

Yes it is the only way.

private synchronized myMethod() {
    // do work
}

is equivalent to:

private myMethod() {
    synchronized(this) {
         // do work
    }
}

So if you want to synchronize on an other instance than this, you have no other choice but declaring the synchronized block inside the method.

like image 124
Jean Logeart Avatar answered Oct 07 '22 07:10

Jean Logeart


It would be better to use a synchronized list in this case:

List<X> list = Collections.synchronizedList(new ArrayList<X>());

The collections API provides synchronized wrapper collections for thread safety.

Synchronizing on the list in the method body will block other threads that need to access the list for the entire lifetime of the method.

The alternative is manually synchronize on all access to the list:

private void doSomethingWithTheCollectionX(List<?> collectionX){
    ...
    synchronized(collectionX) {
       ... e.g. adding to the list
    }

    ...

    synchronized(collectionX) {
       ... e.g. updating an element
    }

 }
like image 33
M A Avatar answered Oct 07 '22 07:10

M A