How to lock a method for the whole class using synchronization?

I know when you want the locking method to be executed by only one thread, you declare it with the synchronized .

What about classes, how to ensure that the entire class of objects is blocked when the thread executes some code in an instance of this class?

In other words, when a thread executes an object method, no other thread should be allowed to execute the same method even in another instance of the same class.

+6
java multithreading
source share
8 answers

You synchronize on a specific object, both a specific static lock object and a class object (what happens when static methods are declared synchronized):

 class X { private static final Object lock = new Object(); public void oneAtATime() { synchronized (lock) { // Do stuff } } } class Y { public void oneAtATime() { synchronized (Y.class) { // Do stuff } } } 

Each option has its pros and cons; locking on a class allows another code, outside the class, to use the same lock for its own reasons (which allows it to organize higher-level synchronization than what you provide), while the static final Object lock approach allows you to disable it by creating the lock field is closed (which simplifies the argument about locking and avoids locking your code because someone wrote bad code).

Of course, you can also use some synchronization mechanism from java.util.concurrent , such as explicit Lock s, which provide more control over the lock (and ReentrantLock currently performs slightly better than implicit locks under a high level of competition).


Edit: Please note that static / global locks are not a great way - this means that every instance of a class ever created will essentially be bound to all other instances (which, in addition to creating it is more difficult to check or read the code, can seriously damage scalability). I assume that you are doing this to synchronize some kind of global state? In this case, I would consider transferring this global / static state to a class and implement synchronization for each instance, not globally.

Instead of this:

 class Z { private static int state; public void oneAtATime(){ synchronized (Z.class) { state++; } } } 

Do it like this:

 class State { private int value; public synchronized void mutate(){ value++; } } class Z { private final State state; public Z(State state){ this.state = state; } public void oneAtATime(){ state.mutate(); } } // Usage: State s1 = new State(), s2 = new State(); Z foo = new Z(s1); Z bar = new Z(s1); Z frob = new Z(s2); Z quux = new Z(s2); 

Now foo and bar are still connected to each other, but they can work independently of frob and quux .

+8
source share

If you use static synchronized methods, they are locked through Class Lock. You can also declare a static object in a class and lock it in a method that I believe, for example:

 private static final Object STATIC_LOCK = new Object(); private void foo() { synchronized (STATIC_LOCK) { //do stuff... } } 
+5
source share

In this method you can use static Mutex . Therefore, any parallel thread blocks inside the method, and the other starts it regardless of which object the class belongs to. I do not think that there is any special keyword for creating the same effect as synchronized .

This is a pretty aggressive synchronization, I would avoid it as much as possible.

+2
source share

Sync over the static field of your class or the class itself:

 synchronized(MyClass.class) { // mutually excluded method body } 
+2
source share

Both threads must use this construct.

 public void someMethod() { synchronized(ClassThatShouldBeProtected.class) { someSynchronizedCode(); } } 

This approach is beneficial in that the class itself is an object, and therefore it has a monitor. Then you do not need an artificial static instance.

+1
source share

There is no built-in mechanism for this. Create your own static lock attribute and make sure you lock it and unlock it in each method. Don't forget about exceptions - make sure you unlock it in the "finally" section.

0
source share

This should work:

 public class MyClass { void synchronizedMethod() { synchronized (MyClass.class) { // synchronized on static level } } } 

What a "missing" representation of a runtime representation of a class to block. This is possible because any object can be used as a mutex in Java.

0
source share

http://www.janeg.ca/scjp/threads/synchronization.html

talks about several ways to achieve it. in general, locks are prohibitive and prevent the use of threads. therefore, critical code should be minimized as much as possible.

Do you want to lock the class lever to access static class variables or to protect access to the class’s external shared resource? in this case you must have a separate lock when accessing it.

0
source share

All Articles