Paul
Paul

Reputation: 608

Threading sync clarifcation

Just want to be sure I understand locking

public class MySync {
    public static synchronized byte[] getRes(String str1, String str2) throws Exception {
        ...
        return new byte[myLen];
    }
    //no other methods
}
public class MyClass extends MyClass2 {
    public MyStuff getStuff (SomeObj obj)   {
        byte[] res =  MySync.getRes(s1,s2);
        ...
    }
    ...
}

Thread 1 calls MyClass
Thread 2 calls MyClass
Thread 3 calls MyClass
T1 calls getres.
T2 waits for T1 to finish with its lock on MySync class
T3 waits for T1 to finish with its lock on MySync class
T1 finishes
T3 calls getres (i.e. order is/is not preserved?)
T2 waits for T3 to finish
T3 finishes
T2 calls getres

yes?

getRes is now "bottleneck"; threads need to wait in "queue"?
Note, I do want this for my application. Only one thread permitted per operation.

The below would accomplish the same as above, except lock is on myLock class?
It is preferred, why?

public class MySync {
    private static final Object myLock = new Object();
public byte[] getRes(String str1, String str2) throws Exception {
        synchronized (myLock) {
            ...
                return new byte[myLen];
        }

public class MyClass extends MyClass2 {
public MyStuff getStuff (SomeObj obj)   {
    byte[] res =  new MySync().getRes(s1,s2);
    ...
}

Upvotes: 0

Views: 58

Answers (2)

rocketboy
rocketboy

Reputation: 9741

The order of threads acquiring the lock is random in case of synchronize.

You can use a lock to dictate the order though.

Also, in case 1 the lock is over the entire Class object in latter case its just over the lock.

Upvotes: 0

sanbhat
sanbhat

Reputation: 17622

In case of

public static synchronized byte[] getRes(String str1, String str2)

the implicit lock will be the class instance which is MySync.class (since its a static synchronized method). So yes, you are right, its mutually exclusive.

In case of

public class MySync {
    private static final Object myLock = new Object();
public byte[] getRes(String str1, String str2) throws Exception {
        synchronized (myLock) {

the result is same, because your lock myLock is static and its shared across multiple instances of your MySync class

Below method is preferred because the MySync.class object will not have overhead of getting locked/unlocked by threads, instead there is a dedicated myLock object

As mentioned in the comment by @BoristheSpider, Lock objects introduced by Java5 gives the programmer much more flexibility in managing locks on a method/block and it is also more readable.

Upvotes: 3

Related Questions