Publishing thread safe object [duplicate] - java

According to the Java Language Specification, constructors cannot be marked synchronized because other threads cannot see the object being created until the thread creating it has finished it. This seems a bit odd, because I can indeed have another thread view the object while it's being constructed:
public class Test {
public Test() {
final Test me = this;
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
}
}.start();
}
}
I know that this is a pretty contrived example, but it seems in theory that someone could come up with a more realistic case where marking the constructor synchronized would be legitimate in order to prevent races with threads like this one.
My question is this: is there a reason that Java would specifically disallow the synchronized modifier on a constructor? Perhaps my above example is flawed, or perhaps there really is no reason and it's an arbitrary design decision. In either case, I'm really curious and would love to know the answer.

If you really need synchronization of the rest of the constructor versus any threads which anyhow gets a reference to your not-yet-totally-constructed object, you can use a synchronized-block:
public class Test {
public Test() {
final Test me = this;
synchronized(this) {
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
synchronized(me) {
// do something dangerous with 'me'.
}
}
}.start();
// do something dangerous with this
}
}
}
Usually it is considered bad style to "give out" your not-yet-constructed object like this, so a synchronized constructor is not necessary.
In some corner cases a synchronized constructor would be useful. Here is a more realistic example, from the discussion of Bozho's answer:
public abstract class SuperClass {
public SuperClass() {
new Thread("evil") { public void run() {
doSomethingDangerous();
}}).start();
try {
Thread.sleep(5000);
}
catch(InterruptedException ex) { /* ignore */ }
}
public abstract void doSomethingDangerous();
}
public class SubClass extends SuperClass {
int number;
public SubClass () {
super();
number = 2;
}
public synchronized void doSomethingDangerous() {
if(number == 2) {
System.out.println("everything OK");
}
else {
System.out.println("we have a problem.");
}
}
}
We want that the doSomethingDangerous() method is only called after construction of our SubClass object is complete, e.g. we only want the "everything OK" output. But in this case, when you only can edit your SubClass, you have no chance of achieving this. If the constructor could be synchronized, it would solve the problem.
So, what we learn about this: never do something like I did here in the superclass constructor, if your class is not final - and don't call any non-final methods of your own class from your constructor.

The question has been raised on a discussion list used by the writers of the Java concurrent API and the Java Memory Model. Several answers were given, in particular Hans Boehm replied:
Some of us (myself included IIRC) actually argued during the Java memory model deliberations that synchronized constructors should be allowed. Now I could go either way on it. Client code shouldn't use races to communicate the reference, so it shouldn't matter. But if you don't trust the clients of [your class], I think synchronized constructors could possibly be useful. And that was much of the reasoning behind final field semantics. [...] As David said, you can use synchronized blocks.

Because synchronized guarantees that actions on the same objects are not to be performed by multiple threads. And when the constructor is called you still don't have the object. It is logically impossible for two threads to access the constructor of the same object.
In your example, even if a method is invoked by the new thread, it is no longer about the constructor - it is about the target method being synchronized or not.

Constructor Modifiers section in JLS clearly says
There is no practical need for a constructor to be synchronized, because it would
lock the object under construction, which is normally not made available to other
threads until all constructors for the object have completed their work.
So there is no need for constructor to be synchronized.
Also it is not recommended to give out the objects reference(this) before object is created. One of the possible ambiguous situations would be to give out the objects reference is superclass constructor when subsclass object is being created.

In your example, the constructor is only actually called once from one thread.
Yes, it is possible to get a reference to an incompletely constructed Object (some discussions around double check locking and why it is broken reveal this problem), however, not by calling the constructor a second time.
Syncronized on the constructor would prevent two threads from calling the constructor on the same Object simultaneously, and that is not possible, as it is never possible to call the constructor on an object instance twice, period.

I see little reason to forbid constructors to be synchronized. It would be useful in many scenarios in multi-threaded applications. If I understand the Java Memory Model correctly (I read http://jeremymanson.blogspot.se/2008/11/what-volatile-means-in-java.html) the following simple class could have benefited from a synchronized constructor.
public class A {
private int myInt;
public /*synchronized*/ A() {
myInt = 3;
}
public synchronized void print() {
System.out.println(myInt);
}
}
In theory, I believe a call to print() could print "0". This could happen if an instance of A is created by Thread 1, the reference to the instance is shared with Thread 2, and Thread 2 calls print(). If there is no special synchronization between the write myInt = 3 of Thread 1 and the read of the same field by Thread 2, Thread 2 is not guaranteed to see the write.
A synchronized constructor would fix this issue. Am I right about this?

The following code can achieve the expected result for synchronized constructor.
public class SynchronisedConstructor implements Runnable {
private int myInt;
/*synchronized*/ static {
System.out.println("Within static block");
}
public SynchronisedConstructor(){
super();
synchronized(this){
System.out.println("Within sync block in constructor");
myInt = 3;
}
}
#Override
public void run() {
print();
}
public synchronized void print() {
System.out.println(Thread.currentThread().getName());
System.out.println(myInt);
}
public static void main(String[] args) {
SynchronisedConstructor sc = new SynchronisedConstructor();
Thread t1 = new Thread(sc);
t1.setName("t1");
Thread t2 = new Thread(sc);
t2.setName("t2");
t1.start();
t2.start();
}
}

Such a synchronization might make sense in some very rare cases, but I guess, it's just not worth it:
you can always use a synchronized block instead
it'd support coding in a pretty strange way
on what should it synchronize? A constructor is a sort-of static method, it works on an object but gets called without it. So synchronizing on the class also makes (some) sense!
When in doubt, leave it out.

Note that constructors cannot be synchronized — using the synchronizedkeyword with a constructor is a syntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed.

Related

Singletone method

I need a method that will always be executed in one instance. For example, this method was called from different class instances and different threads at the same time. In this case, they should be executed one at a time, and not simultaneously, despite the fact that they are called from different instances.
I cant make it just static and synchronized, because it have a lot of inner code, which cant be refactored to static
For now I have next idea:
private static Boolean isMethodRun = false;
public void singletoneMethod() {
synchronized(Boolean) {
if (!isMethodRun) {
isMethodRun = true;
} else {
for (int i = 0; i < 10; i++) {
if (isMethodRun) {
Thread.sleep(2_000);
} else {
isMethodRun = true;
break;
}
}
}
}
try {
//inner code
} catch (Throwable e) {
//logs
throw e;
} finally {
isMethodRun = false;
}
}
Is there any prettier way to get such functionality
The easiest way would be to synchronize the method. Since you appear to have defined the isMethodRun variable static, it looks like you would want to synchronize on a static thing:
private static final Object lock = new Object();
public void singletoneMethod() {
synchronized (lock) {
// The code you want only to execute one-at-a-time.
}
}
You could have synchronized on the class - synchronized (WhateverYourClass.class) - but that is vulnerable to anybody in the JVM synchronizing on the class elsewhere. Using an inaccessible Object like this is more robust.
So basically you want only one singletonMethod call to proceed at a time1.
This is the simplest solution:
public static synchronized void singletonMethod() {
// your business logic here
}
You said:
I can't make it just static and synchronized, because it have a lot of inner code, which can't be refactored to static
I'm not convinced that it can't be refactored2, but if you say so, here are some alternatives:
private static final Object lock = new Object(); // Must be static!
public void singletonMethod() {
synchronized (lock) {
// your business logic here
}
}
Or
public static synchronized void oneAtATime(Runnable runnable) {
runnable.run();
}
You could use the oneAtATime method like this:
oneAtATime(() -> { // your business logic here }); // Java 8+
oneAtATime(new Runnable() {
public void run() {
// your business logic here
}
});
Apart from the first one (at the top), these alternatives all allow you to refer to instance variables in the "business logic". You just need to implement the "business logic" in the appropriate scope. (And even in the first case, it is trivial to pass an instance reference to a static method so that it can call methods on the instance.)
To use the above in a thread-safe fashion, you need to ensure that the "business logic" is all thread-safe. That will depend on other code in the application; e.g. how other threads / methods use any shared objects that this "business logic" is operating on.
why would static be needed here? Can't it just be public synchronized void singletonMethod? Or do the memory barriers not work for accessing static fields? – luk2302 25 mins ago
We need a static lock or a static synchronized method in order to meet the stated requirement that only one call is in progress at a time. If there is more than one lock, you won't get serialization.
It would be possible to implement the "one at a time" logic as a synchronized instance method of a (properly implemented) Singleton class. However, there is not much point unless you have other good uses for the Singleton class. (Bear in mind that the Singleton pattern brings problems of its own.)
1 - This is not what the term "singleton" conventionally means ...
2 - In fact the refactoring required is trivial. Just put your business logic into an instance method of YourClass declared as (say) businessLogic(). Then you can define the one-at-a-time method in YourClass as follows: static synchronized void singleton(YourClass arg) { arg.businessLogic(); }. You would typically use it (within YourClass) like this: YourClass.singleton(this);

Best practise to create singleton in concurrent environment?

I'm seeking an answer to a question similar to Is it appropriate to use AtomicReference.compareAndSet to set a reference to the results of a database call? but with different requirement.
The goal is to create an instance of ObjectWithSideEffectConstructor only once to avoid duplicate side effects. The construction must happen in setUp(). Multiple threads will call setUp(). Similarly there will be a tearDown() for reclaiming the resource from the object, which is omitted here. Question: what is the best practice to achieve the goal?
Simply using AtomicReference will not be enough, because the constructor will be executed first, so as the side effect.
private static AtomicReference<ObjectWithSideEffectConstructor> ref =
new AtomicReference<ObjectWithSideEffectConstructor>()
void setUp() {
ref.compareAndSet(null, new ObjectWithSideEffectConstructor());
}
Using the answer from Is it appropriate to use AtomicReference.compareAndSet to set a reference to the results of a database call? will not work, because volatile lacks of synchronization. There will be window that multiple threads enters if.
private static volatile ObjectWithSideEffectConstructor obj;
void setUp() {
if (obj == null) obj = new ObjectWithSideEffectConstructor();
}
Simple fix would be
private static ObjectWithSideEffectConstructor obj;
private static final Object monitor = new Object();
void setUp() {
synchronized (monitor) {
if (obj == null) obj = new ObjectWithSideEffectConstructor();
}
}
Similarly, DCL with volatile monitor may give better read performance. But both requires some level of synchronization, thus expect worse performance.
Also we can use FutureTask. It is more efficient because once the object is created, subsequent FutureTask.get() will return without blocking. But it is definitely much more complicated than synchronized.
private static final AtomicReference<FutureTask<ObjectWithSideEffectConstructor>> ref =
new AtomicReference<FutureTask<ObjectWithSideEffectConstructor>>();
void setUp() {
final FutureTask<ObjectWithSideEffectConstructor> future =
new FutureTask<ObjectWithSideEffectConstructor>(
new Callable<ObjectWithSideEffectConstructor>() {
#Override
public ObjectWithSideEffectConstructor call() throws InterruptedException {
return new ObjectWithSideEffectConstructor();
}
}
);
if (ref.compareAndSet(null, future)) future.run();
ref.get().get();
}
Thanks for suggestions.
If you're talking about threadsafe lazy initialization of the singleton, here is a cool code pattern to use that accomplishes 100% threadsafe lazy initialization without any synchronization code:
public class MySingleton {
private static class MyWrapper {
static MySingleton INSTANCE = new MySingleton();
}
private MySingleton () {}
public static MySingleton getInstance() {
return MyWrapper.INSTANCE;
}
}
This coding pattern is known as the Initialization-on-demand holder idiom. It will instantiate the singleton only when getInstance() is called, and it's 100% threadsafe! It's a classic.
It works because the class loader has its own synchronization for handling static initialization of classes: You are guaranteed that all static initialization has completed before the class is used, and in this code the class is only used within the getInstance() method, so that's when the class loaded loads the inner class.
Implementing Singleton in Java 5 or above version using Enum:
Enum is thread safe and implementation of Singleton through Enum ensures that your singleton will have only one instance even in a multithreaded environment.
Let us see a simple implementation:
public enum SingletonEnum
{
INSTANCE;
public void doStuff()
{
System.out.println("Singleton using Enum");
}
}
// How to use in other classes
public static void main(String[] args)
{
SingletonEnum.INSTANCE.doStuff();
}
Always use the enum type for singletons, not only does it enforce the singleton elegantly, it also prevents common programming errors like when a singleton inherits a clone() method from its superclass and the programmer forgets to override it with a private method declaration. Or when you forget to override deserialisable, and allow programmers to serialise your singleton, declare a new instance, and then deserialise the old one.
Alternatively, if you use a static factory pattern, you can declare instance fields transient and use a readresolve method. This provides the flexibility if you might change your mind about whether it should be a singleton later in the design process.
Credit: Answer based on Effective Java by J Bloch (Item 3), a book every Java programmer should read, own and refer to regularly...
I assume you only want one ObjectWithSideEffectConstructor. There's a question here as to whether 1) it's the side effect happening twice your want to avoid, or 2) you just need to end up with a consistent (singleton) reference.
Either way, synchronized is a good standard option. It will keep other threads from constructing a second instance, while the first thread is in setup.
If you're in situation 1), using synchronized is probably required. If performance after startup were critical, you could possibly consider preceding the synchronized section with an AtomicReference.get() fast-path, to enable the synchronized section to be avoided after startup is complete.
If you're in situation 2), then -- it's not really clear from your question -- there is a side-effect of construction, but you don't care about duplicating that -- just so long as the client code only "sees" a consistent single reference.
In that second case, you could use AtomicReference.get() to check whether it's already initialized, and return if so. Threads would then enter the "race section" where they would construct (potentially multiple) ObjectWithSideEffectConstructor. Lastly, there would be a compareAndSet so that only one thread set the singleton.. with failing threads falling back to anAtomicReference.get() to take the correct singleton.
Performancewise, a single call to AtomicReference is faster than a synchronized block -- but I'm not sure if, with the double- and triple-checking & construction of unwanted side-effect objects, the second approach would be. A simple synchronized block might, again, be simpler & faster.
I'd be interested to see some measurements.
The synchronized method would be the way to go. If you actually need the performance you need to restructure your code to have a single-threaded pre-initialization. Using any other form will cause side-effects as described in the singleton pattern.
For what it's worth, the FutureTask approach doesn't actually require all of that code; the AtomicReference is not needed, and there shouldn't be any need to call both run() and get(). So you can simplify it slightly:
private static final Future<ObjectWithSideEffectConstructor> future =
new FutureTask<>(
new Callable<ObjectWithSideEffectConstructor>() {
#Override
public ObjectWithSideEffectConstructor call() throws InterruptedException {
return new ObjectWithSideEffectConstructor();
}
}
);
void setUp() {
future.run(); // or future.get(), if you want to get any exception immediately
}
Furthermore, with Java 8, the initialization expression can be written much more briefly; the above can be reduced to just:
private static final Future<ObjectWithSideEffectConstructor> future =
new FutureTask<>(ObjectWithSideEffectConstructor::new);
void setUp() {
future.run(); // or future.get(), if you want to get any exception immediately
}

"synchronized(this)" vs. "synchronized((BaseClass)this)" in Java?

This is a successor of my previous question, Is this variable being safely accessed by using synchronization?
For the following program,
Class SubClassB extends SuperClassA {
protected int c;
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized ( (SuperClassA) this) {
c--;
}
}
}
Would the counter "c" be accessed thread safe ? I am not sure that in the "dec()" method, is the SuperClassA cast "this" reference a valid object for the synchronized block ? If yes, would the two synchronized blocks lock the same "this" object ? (As it seems to me that "(SuperClassA) this" is not equal to "this")
This strange simulated code comes from the following real life example where SuperClassA is a base class that is not supposed to be modified,
Class SuperClassA {
protected int c;
public void dec() {
synchronized (this) {
c--;
}
}
}
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
super.dec();
}
}
In this example, the "dec()" method in SubClassB calls its superclass's "dec()" method which performs a lock to a "this" object that I suppose to be "SuperClassA.this". If the locked object in SubClassB's "inc()" method is not exactly the same as the locked object in SubClassB's "dec()" method, then I am wondering the inherited counter "c" in SubClassB may NOT be safely accessed by different threads. I feel that there is some ambiguities in using the "this" reference in synchronized blocks.
In the real life example, if I want SubClassB's counter "c" to be thread safe, do I need to add one more synchronized block in its "dec()" method, like this,
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized (this) {
super.dec();
}
}
}
But it seems that such added block is not elegant and may be redundant !
Does anyone have some ideas on these questions. Thanks in advance.
Lawrence
The code is thread-safe, because (SomeObject) this adn this are the same object. A cast doesn't transform an object into another object.
The code lacks encapsulation, though, because it lets any subclass access the protected c field in an unsynchronized way. So, any subclass might use c++ or c-- without any synchronization. The field should be private.
Would the counter "c" be accessed thread safe ?
Yes, it's using the same lock object.
I am not sure that in the "dec()" method, is the SuperClassA cast "this" reference a valid object for the synchronized block ?
Yes.
If yes, would the two synchronized blocks lock the same "this" object ? (As it seems to me that "(SuperClassA) this" is not equal to "this")
Yes. Even if you cast the instance to something it can be casted to (even Object), it'll still refer to the same object.
[...] But it seems that such added block is not elegant and may be redundant !
It is redundant. Extra synchronization is required only if you call multiple synchronized methods and the combined effect must be atomic.
it seems to me that "(SuperClassA) this" is not equal to "this"
Wrong; synchronization is done on objects, and casting only changes the compile-time type, is has no effect on object identity.
Thus, you don't have to add an extra synchronization in the subclass.
All three examples are correct as far as synchronization is concerned.
There's only one monitor associated with any object.
Casting this to a base class inside synchronized makes no difference.
For the same object, it doesn't matter whether synchronized(this) is invoked in the context of the derived class or the base class: the same lock is used in both cases.

Java: reference escape

Read that the following code is an example of "unsafe construction" as it allows this reference to escape. I couldn't quite get how 'this' escapes. I am pretty new to the java world. Can any one help me understand this.
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
The example you have posted in your question comes from "Java Concurrency In Practice" by Brian Goetz et al. It is in section 3.2 "Publication and escape". I won't attempt to reproduce the details of that section here. (Go buy a copy for your bookshelf, or borrow a copy from your co-workers!)
The problem illustrated by the example code is that the constructor allows the reference to the object being constructed to "escape" before the constructor finishes creating the object. This is a problem for two reasons:
If the reference escapes, something can use the object before its constructor has completed the initialization and see it in an inconsistent (partly initialized) state. Even if the object escapes after initialization has completed, declaring a subclass can cause this to be violated.
According to JLS 17.5, final attributes of an object can be used safely without synchronization. However, this is only true if the object reference is not published (does not escape) before its constructor finished. If you break this rule, the result is an insidious concurrency bug that might bite you when the code is executed on a multi-core / multi-processor machines.
The ThisEscape example is sneaky because the reference is escaping via the this reference passed implicitly to the anonymous EventListener class constructor. However, the same problems will arise if the reference is explicitly published too soon.
Here's an example to illustrate the problem of incompletely initialized objects:
public class Thing {
public Thing (Leaker leaker) {
leaker.leak(this);
}
}
public class NamedThing extends Thing {
private String name;
public NamedThing (Leaker leaker, String name) {
super(leaker);
}
public String getName() {
return name;
}
}
If the Leaker.leak(...) method calls getName() on the leaked object, it will get null ... because at that point in time the object's constructor chain has not completed.
Here's an example to illustrate the unsafe publication problem for final attributes.
public class Unsafe {
public final int foo = 42;
public Unsafe(Unsafe[] leak) {
leak[0] = this; // Unsafe publication
// Make the "window of vulnerability" large
for (long l = 0; l < /* very large */ ; l++) {
...
}
}
}
public class Main {
public static void main(String[] args) {
final Unsafe[] leak = new Unsafe[1];
new Thread(new Runnable() {
public void run() {
Thread.yield(); // (or sleep for a bit)
new Unsafe(leak);
}
}).start();
while (true) {
if (leak[0] != null) {
if (leak[0].foo == 42) {
System.err.println("OK");
} else {
System.err.println("OUCH!");
}
System.exit(0);
}
}
}
}
Some runs of this application may print "OUCH!" instead of "OK", indicating that the main thread has observed the Unsafe object in an "impossible" state due to unsafe publication via the leak array. Whether this happens or not will depend on your JVM and your hardware platform.
Now this example is clearly artificial, but it is not difficult to imagine how this kind of thing can happen in real multi-threaded applications.
The current Java Memory Model was specified in Java 5 (the 3rd edition of the JLS) as a result of JSR 133. Prior to then, memory-related aspects of Java were under-specified. Sources that refer to earlier versions / editions are out of date, but the information on the memory model in Goetz edition 1 is up to date.
There are some technical aspects of the memory model that are apparently in need of revision; see https://openjdk.java.net/jeps/188 and https://www.infoq.com/articles/The-OpenJDK9-Revised-Java-Memory-Model/. However, this work has yet to appear in a JLS revision.
I had the exact same doubt.
The thing is that every class that gets instantiated inside other class has a reference to the enclosing class in the variable $this.
This is what java calls a synthetic, it's not something you define to be there but something java does for you automatically.
If you want to see this for yourself put a breakpoint in the doSomething(e) line and check what properties EventListener has.
My guess is that doSomething method is declared in ThisEscape class, in which case reference certainly can 'escape'.
I.e., some event can trigger this EventListener right after its creation and before execution of ThisEscape constructor is completed. And listener, in turn, will call instance method of ThisEscape.
I'll modify your example a little. Now variable var can be accessed in doSomething method before it's assigned in constructor.
public class ThisEscape {
private final int var;
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
);
// more initialization
// ...
var = 10;
}
// result can be 0 or 10
int doSomething(Event e) {
return var;
}
}
I just had the exact same question while reading "Java Concurrency In Practice" by Brian Goetz.
Stephen C's answer (the accepted one) is excellent! I only wanted to add on top of that one more resource I discovered. It is from JavaSpecialists, where Dr. Heinz M. Kabutz analyzes exactly the code example that devnull posted. He explains what classes are generated (outer, inner) after compiling and how this escapes. I found that explanation useful so I felt like sharing :)
issue192 (where he extends the example and provides a race condition.)
issue192b (where he explains what kind of classes are generated after compiling and how this escapes.)
This confused me quite a bit, as well. Looking at the full code example and also just reading it a million times helped me finally see it. Compliments to Stephen C, though, whose answer is quite thorough and offers a simplified example.
The problem is source.registerListener(), which is provided as a member of ThisEscape. Who knows what that method does? We don't. ThisEscape doesn't specify, because it's declared in an interface within ThisEscape.
public class ThisEscape {
// ...
interface EventSource {
void registerListener(EventListener e);
}
interface EventListener {
void onEvent(Event e);
}
// ...
}
Whatever class implements EventSource provides the implementation for registerListener() and we have no idea what it might do with the provided EventListener. But, because EventListener is a part of ThisEscape, it also contains a hidden reference to it. That's why this example is so tricky. Basically, while ThisEscape is being constructed, a reference to it is published via source.registerListener(<reference>), and who knows what that EventSource will do with it.
It's one of the many great cases for a private constructor and static factory method. You can confine construction to one line in the static factory method, ensuring its completion before passing it to source.

How to lock a method for a whole class using synchronized?

I know when you want to lock method to be executed by only one thread you declare it with synchronized keyword.
What about classes, how to provide a lock on an entire class of objects when a thread
is executing some code on an instance of that class?
In other words, when a thread is executing a method on an object, no other thread should be
allowed to execute the same method even on a different instance of the same class.
You synchronize on a specific object, either some designated static lock object, or the class object (which happens when static methods are declared to be 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 variant has its own pros and cons; locking on the class allows other code, outside of the class, to use the same lock for its own reasons (which allows it to orchestrate more high-level synchronization than what you provide) while the static final Object lock approach lets you prohibits it by making the lock field private (which makes it easier to reason about the locking and avoid your code from deadlocking because someone else wrote bad code).
You could of course also use some synchronization mechanism from java.util.concurrent, like explicit Locks, which provide more control over locking (and ReentrantLock currently performs a little better than implicit locks under high contention).
Edit: Note that static/global locks aren't a great way to go - it means every instance of the class ever created will essentially be tied to every other instance (which, aside from making it harder to test or read the code, can severely harm scalability). I assume you do this to synchronize some kind of global state? In that case, I'd consider wrapping that global/static state in a class instead, and implement synchronization per-instance rather than globally.
Instead of something like 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 tied to each other, but they can work independently from frob and quux.
If you use static synchronized methods, they are locked via the Class Lock. You can also declare a static Object in the class and lock that in a method I believe via something like:
private static final Object STATIC_LOCK = new Object();
private void foo() {
synchronized (STATIC_LOCK) {
//do stuff...
}
}
You could use a static Mutex inside that method. So any concurrent thread is blocking inside the method while another is running it no matter what object of the class it belongs to. I don't think there is any special single keyword to produce the same effect like synchronized.
It is a rather aggressive synchronization, I would avoid it as much as possible.
Synchronize on static field of your class, or the class itself:
synchronized(MyClass.class) {
// mutually excluded method body
}
Both threads must use this construction
public void someMethod() {
synchronized(ClassThatShouldBeProtected.class) {
someSynchronizedCode();
}
}
This approach benefits from the fact, that class itself is an object and therefore it has a monitor. Then you don't need any artificial static instance.
There is no built-in mechanism for this. Create your own static lock attribute, and make sure you lock it and unlock it in every method. Don't forget about exceptions - make sure you unlock it in the "finally" sections.
This should work:
public class MyClass {
void synchronizedMethod() {
synchronized (MyClass.class) {
// synchronized on static level
}
}
}
Which 'missuses' the class's runtime-representation for locking. This is possible as any object can be used as a mutex in Java.
http://www.janeg.ca/scjp/threads/synchronization.html
talks about several ways to achieve it.
in general, locks are prohibitive and hinder benefits of threading. so the critical code should be minimized as much as its possible.
do you want a class lever lock to access static variables of the class or is it for protecting access to a common external resource the class? in which case you should proly have a separate lock while accessing it.

Categories