views:

110

answers:

3

I know in C# when you have an object you want to use as a lock for multi-threading, you should declare it as static inside of a class, which the class instance will be running in a separate thread.

Does this hold true for Java as well? Some examples online seem to declare the lock object as only final...

Edit: I have a resource that I want to limit to only one thread access at a time. A class that extends Thread will be used to create multiple instances and started at the same time. What should I use?

Thanks.

+3  A: 

Depends on in which context they are to be used. If you want a per-instance lock, then leave static away. If you want a per-class lock, then use static. Further indeed keep it final.

BalusC
Thanks, owe you another one :-P
kesun421
If you want a per-class lock, then you are probably doing something wrong (it can be useful for the likes of caches, but generally mutable statics are bad).
Tom Hawtin - tackline
I have a resource that I want to limit to only one thread access at a time. A class that extends Thread will be used to create multiple instances and started at the same time. What should I use?
kesun421
Then use a per-class (`static`) lock, or consider using a `synchronized` method for the particular puspose.
BalusC
Gotcha, thanks.
kesun421
+2  A: 

No

In Java it is possible to use non-static members as locks.

private Object lock = new Object();

public void test(){
    synchronized (lock) {
      // your code  
    }
}
Upul
Yes, that compiles :)
BalusC
As IntelliJ likes to tell me "Synchronization on a non-final field is unlikely to have useful semantics."
Kylar
+1  A: 

Simple answer, no. Long answer, it depends on what you want.

private static final Object STATIC_LOCK = new Object();

private final Object lock = new Object();

public void doSomething() {
    synchronized (STATIC_LOCK) {
        // At most, one thread can enter this portion
    }

    synchronized (lock) {
        // Many threads can be here at once, but only one per object of the class
    }
}

With that being said, I would recommend you look at the locks provided in java.util.concurrent.locks. Using java.util.concurrent.locks.Lock you can do the following:

Lock l = ...;
l.lock();
try {
    // access the resource protected by this lock
} finally {
    l.unlock();
}  
mangoDrunk
That clarifies even more. Thanks.
kesun421