Phantasma
Phantasma

Reputation: 55

Is there a design pattern or best practice in Java for synchronized access to objects, at a method level?

I am writing an SDK that exposes an interface to an object that represents a hardware device.

Multiple threads may not be allowed to access this interface at the same time. A common misuse of this would be to have the GUI thread (on Android, for instance) trying to access the object the same time as an asynchronous task.

The object need not be re-entrant.

Being newer to Java, especially concepts surrounding concurrency specifically for Java, I'm not finding any elegant solutions at this point. The synchronized keyword is not apropo here, as method a should not be free to be called while method b is being invoked,

'''java

public class A
    {
        private final Semaphore semaphore = new Semaphore(1);
        private SomeNativeClass someNativeObject;

        public boolean doSomething(int a){
            try{
                semaphore.acquire();
            } catch (InterruptedException e){
                return false;
            }
            if( false == someNativeObject.funcA()){
                semaphore.release();
                return false;
            }
            semaphore.release();

            return true;
        }
        public boolean doSomethingElse(int b){
            try{
                semaphore.acquire();
            } catch (InterruptedException e){
                return false;
            }
            if( false == someNativeObject.funcD()){
                semaphore.release();
                return false;
            }
            if( false == someNativeObject.funcC()) {
                semaphore.release();
                return false;
            }
            semaphore.release();
            return true;
        }
    }

I'm sure this would work, but find it error prone (especially without destructors that go out of scope thus releasing the semaphore, like in C++)

How is this done in Java, in general? I do not want to put the responsibility of this on the client, as the implementation is rightly abstracted from the interface.

Upvotes: 0

Views: 118

Answers (1)

JohnnyAW
JohnnyAW

Reputation: 2876

you can use synchronized-keyword, since it would synchronize all methods on this-object, so doSomething() and doSomethingElse can't be run concurrently:

public class A
{
    private SomeNativeClass someNativeObject;

    public synchronized boolean doSomething(int a){
        return someNativeObject.funcA();
    }
    public synchronized  boolean doSomethingElse(int b){
        return someNativeObject.funcD() && someNativeObject.funcC();
    }
}

if you need to synchronize on some other object you can use synchronized-block

Upvotes: 2

Related Questions