Can I change my code from:
class Sample{
private Object _lock=new Object();
public void someMethod(){
synchronized(_lock){
doSomething();
}
}
}
to:
class Sample{
private ISchedulingRule _lock=new SomeSchedulingRule();
public void someMethod(){
try{
Job.getManager().beginRule(_lock);
doSomething();
}finally{
Job.getManager().endRule(_lock);
}
}
}
I'm reading "java concurrency in practice", and they say if I wanna use some explicit lock, I have to guarantee the memory visibility.
So the question is:
If I can guarantee the memory visibility, can I use the code at bottom to replace the code at top(replace intrinsic synchronization with eclipse IJobManager.beginRule and IJobManager.endRule)
Assuming the source code I found here is up to date, you can check that the beginRule method calls implicitJob.begin which has a large synchronized(this) block inside.
If your only goal is to achieve synchronization then the answer is yes.
That said, there are some (hidden) gotchas that you need to be aware of. Since JobManager is designed to prevent dead-locks to some extent, then there are somewhat strict rules for using and defining nested rules (a limitation that Java synchronized blocks don't have). There is no public API for checking whether a thread is holding a rule/lock or not. Also, beginRule cannot be canceled by calling interrupt on waiting thread. To name a few.
I just found a web tutorial on concurrency which makes the following statement:
Well, it turns out that a contract of the Lock interface is that it provides the same >memory barrier behaviour as synchronized.
That's referring to the "Lock" interface in java.util.concurrent. I don't know whether it applies to the ISchedulingRule interface which you show here.
Related
I have a class from an external API and I want to create an instance of it and access that object's methods from different threads. My questions are as comments in the following code:
import java.util.concurrent.Executors;
public class ThreadSafetyQuestion {
static class ExternalAPIObject {
void method(){
}
}
private static volatile ExternalAPIObject obj;
static synchronized ExternalAPIObject syncGetObject(){
return obj;
}
public static void main(String[] args) {
Executors.newSingleThreadExecutor().submit(()-> {
ThreadSafetyQuestion.syncGetObject().method();//Is this thread safe?
ExternalAPIObject externalAPIObject = ThreadSafetyQuestion.syncGetObject();
//do some other stuff
externalAPIObject.method();//I doubt this is thread safe. How can I access this method from multiple threads in a safe way?
});
}
}
You are looking at this from the wrong perspective. Thread safe means: when more than one thread invokes these methods nothing bad happens. It is really simple: when method() does manipulate "internal data" without any form of synchronisation - then having more than one thread call method() on the same object can result in a problem.
Thus: all the things that you put up in your question do not matter!
The only thing that matters: what exactly do these methods do that you are invoking?! In other words: there is no point in putting up a singleton to call methods in different threads. Or making the object reference volatile. All these ideas add zero in regards of making things "thread safe". Because you still allow method() to be called on the same object by different threads.
What you have to do instead: carefully check what exactly the methods you are invoking are doing.
And in case you don't want to go there: then create a single singleton that simply delegates calls to method() - but that has its methods marked as synchronized.
So: if you don't know anything about the external API - then one conservative approach is to make sure to always all its methods sequentially. Of course that can affect performance in very negative ways.
Long story short: it seems you are lacking basic understanding of multithreading concepts in Java. Don't go for trial/error then - rather step back and study this topic in depth! Seriously: multi-threading errors are subtle, they often go unnoticed for days or months. The first step in avoiding them: knowing what you are doing (instead of throwing some keywords at a problem that you somehow read about having this or that effect).
So I'm pretty good overall when it comes to the thread-safety of code, but I'm currently encountering a situation where I'm not clear on the best way to handle it.
I have an instance variable, non-final because the enclosing class can change its value. This variable is an object that has several methods that get called on it during the application. Here is a quick sample to show what I mean.
private class Foo{
private FooFoo fooFoo;
public synchronized void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public void doSomething(){
fooFoo.doSomething(); //How do I make this line thread-safe?
}
}
Changing the reference of the fooFoo field is easy, just simple synchronization. But what about when the doSomething() method is called on fooFoo? I'm always hesitant to synchronize on an alien method due to deadlock risk.
In the real cases this is based on, there are many different variations of this. My company's application is a sprawling code base that frequently resembles a bowl of spaghetti, so when it comes to writing any kind of synchronized code I'm extra paranoid, because of the tight coupling and the fact that there are developers not only here in the US, but in an offshore firm in eastern europe working on it and I do not trust all of them to make good coding decisions.
So I'm just looking for the best practice to handle this kind of situation in a multi-threaded environment. Thanks.
fooFoo.doSomething(); //How do I make this line thread-safe?
Hint: You can't make that one line thread-safe unless that is the only line in the whole program that ever accesses the object.
Thread-safety is not about making particular lines of code or particular methods thread safe: It's about making data thread safe.
Does fooFoo refer to a mutable object? If not, then that line already is thread safe. But if the object is mutable, then thread-safety, at a minimum, means insuring that unintended interactions between two or more threads can not put that object into an invalid state; and at the worst case it means insuring the consistency of relationships between the fooFoo object and other objects in your program.
Any time there is an important relationship between two or more pieces of data that are shared between threads, then you probably need to throw a synchronized block around any bit of code that could temporarily violate that relationship, and you need to throw a synchronized block around any bit of code that depends on that relationship---even if the code only looks at the data.
In your case you would have to make doSomething() synchronized too, because you need to lock every time a concurrent access on a mutable part of the class occurs. While you are only reading fooFoo in doSomething, you could at the same time be writing fooFoo in setFooFoo(), thus creating a data race. synchronized essentially causes the function call to take a lock that is associated with the Java-object at entry and to release it once you leave the function.
Alternatively you can use a Lock member inside Foo that you take when you do either. This applies in situations, where you may have multiple independent members that may be accessed safely while the other is being altered. In this case taking two different locks may make your code substantially faster.
For completeness sake it should be mentioned that in some older Java versions (Java 5 only I believe) taking the intrinsic lock of the object through a synchronized method, was substantially slower than using a lock object.
For the deadlock problem: you are right to worry about this, but consider it as a separate issue, after you make your object thread-safe in the first place. The question there is what other locks are taken and it is not possible to answer this with just what you posted. Given your object, synchronizing the read/write on the object can not deadlock by itself, because only one operation can be active at the time, and they do not take any other locks from what you show in your code.
It depends upon what your concerns are for thread safety.
If foo is only delegated to you can simply make it volatile. This will prevent threads from cashing a reference to the old value if the reference is updated. FooFoo can then handle it's own thread safety concerns.
private class Foo{
private volatile FooFoo fooFoo;
public void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public void doSomething(){
fooFoo.doSomething();
}
}
If your concern is about thread safety of Foo itself, and it is doing more then just delegating calls you should synchronize relevant methods.
private class Foo{
private FooFoo fooFoo;
public synchronized void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public synchronized void doSomething(){
fooFoo.doSomething();
}
public synchronized void doSomethingElse() {
int values = fooFoo.getValue();
// do some things
fooFoo.setValue(values + somethingElse);
}
}
I want to know how to use synchronized blocks across classes. What I mean is, I want to have synchronized blocks in more than one class but they're all synchronizing on the same object. The only way that I've thought of how to do this is like this:
//class 1
public static Object obj = new Object();
someMethod(){
synchronized(obj){
//code
}
}
//class 2
someMethod(){
synchronized(firstClass.obj){
//code
}
}
In this example I created an arbitrary Object to synchronize on in the first class, and in the second class also synchronized on it by statically referring to it. However, this seems like bad coding to me.
Is there a better way to achieve this?
Having a static object that is used as a lock typically is not desirable because only one thread at a time in the whole application can make progress. When you have multiple classes all sharing the same lock that's even worse, you can end up with a program that has little to no actual concurrency.
The reason Java has intrinsic locks on every object is so that objects can use synchronization to protect their own data. Threads call methods on the object, if the object needs to be protected from concurrent changes then you can add the synchronized keyword to the object's methods so that each calling thread must acquire the lock on that object before it can execute a method on it. That way calls to unrelated objects don't require the same lock and you have a better chance of having code actually run concurrently.
Locking shouldn't necessarily be your first go-to technique for concurrency. Actually there are a number of techniques you can use. In order of descending preference:
1) eliminate mutable state wherever possible; immutable objects and stateless functions are ideal because there's no state to protect and no locking required.
2) use thread-confinement where you can; if you can limit state to a single thread then you can avoid data races and memory visibility issues, and minimize the amount of locking.
3) use concurrency libraries and frameworks in preference to rolling your own objects with locking. Get acquainted with the classes in java.util.concurrent. These are a lot better written than anything an application developer can manage to throw together.
Once you've done as much as you can with 1, 2, and 3 above, then you can think about using locking (where locking includes options like ReentrantLock as well as intrinsic locking). Associating the lock with the object being protected minimizes the scope of the lock so that a thread doesn't hold the lock longer than it needs to.
Also if the locks aren't on the data being locked then if at some point you decide to use different locks rather than having everything lock on the same thing, then avoiding deadlocks may be challenging. Locking on the data structures that need protecting makes the locking behavior easier to reason about.
Advice to avoid intrinsic locks altogether may be premature optimization. First make sure you're locking on the right things no more than necessary.
OPTION 1:
More simple way would be to create a separate object (singleton) using enum or static inner class. Then use it to lock in both the classes, it looks elegant:
// use any singleton object, at it's simplest can use any unique string in double quotes
public enum LockObj {
INSTANCE;
}
public class Class1 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
OPTION:2
you can use any string as JVM makes sure it's only present once per JVM. Uniqueness is to make sure no-other lock is present on this string. Don't use this option at all, this is just to clarify the concept.
public class Class1 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
Your code seems valid to me, even if it does not look that nice. But please make your Object you are synchronizing on final.
However there could be some considerations depending on your actual context.
In any way should clearly state out in the Javadocs what you want to archive.
Another approach is to sync on FirstClass e.g.
synchronized (FirstClass.class) {
// do what you have to do
}
However every synchronized method in FirstClass is identical to the synchronized block above. With other words, they are also synchronized on the same object. - Depending on the context it may be better.
Under other circumstances, maybe you'd like to prefer some BlockingQueue implementation if it comes down that you want to synchronize on db access or similar.
I think what you want to do is this. You have two worker classes that perform some operations on the same context object. Then you want to lock both of the worker classes on the context object.Then the following code will work for you.
public class Worker1 {
private final Context context;
public Worker1(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Worker2 {
private final Context context;
public Worker2(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Context {
public static void main(String[] args) {
Context context = new Context();
Worker1 worker1 = new Worker1(context);
Worker2 worker2 = new Worker2(context);
worker1.someMethod();
worker2.someMethod();
}
}
I think you are going the wrong way, using synchronized blocks at all. Since Java 1.5 there is the package java.util.concurrent which gives you high level control over synchronization issues.
There is for example the Semaphore class, which provides does some base work where you need only simple synchronization:
Semaphore s = new Semaphore(1);
s.acquire();
try {
// critical section
} finally {
s.release();
}
even this simple class gives you a lot more than synchronized, for example the possibility of a tryAcquire() which will immediately return whether or not a lock was obtained and leaves to you the option to do non-critical work until the lock becomes available.
Using these classes also makes it clearer, what prupose your objects have. While a generic monitor object might be misunderstood, a Semaphore is by default something associated with threading.
If you peek further into the concurrent-package, you will find more specific synchronisation-classes like the ReentrantReadWriteLock which allows to define, that there might be many concurrent read-operations, while only write-ops are actually synchronized against other read/writes. You will find a Phaser which allows you to synchronize threads such that specific tasks will be performed synchronously (sort of the opposite of synchornized) and also lots of data structures which might make synchronization unnecessary at all in certain situations.
All-in-all: Don't use plain synchronized at all unless you know exactly why or you are stuck with Java 1.4. It is hard to read and understand and most probably you are implementing at least parts of the higher functions of Semaphore or Lock.
For your scenario, I can suggest you to write a Helper class which returns the monitor object via specific method. Method name itself define the logical name of the lock object which helps your code readability.
public class LockingSupport {
private static final LockingSupport INSTANCE = new LockingSupport();
private Object printLock = new Object();
// you may have different lock
private Object galaxyLock = new Object();
public static LockingSupport get() {
return INSTANCE;
}
public Object getPrintLock() {
return printLock;
}
public Object getGalaxyLock() {
return galaxyLock;
}
}
In your methods where you want to enforce the synchronization, you may ask the support to return the appropriate lock object as shown below.
public static void unsafeOperation() {
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
public void unsafeOperation2() { //notice static modifier does not matter
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
Below are few advantages:
By having this approach, you may use the method references to find all places where the shared lock is being used.
You may write the advanced logic to return the different lock object(e.g. based on caller's class package to return same lock object for all classes of one package but different lock object for classes of other package etc.)
You can gradually upgrade the Lock implementation to use java.util.concurrent.locks.LockAPIs. as shown below
e.g. (changing lock object type will not break existing code, thought it is not good idea to use Lock object as synchronized( lock) )
public static void unsafeOperation2() {
Lock lock = LockingSupport.get().getGalaxyLock();
lock.lock();
try {
// perform your operation
} finally {
lock.unlock();
}
}
Hopes it helps.
First of all, here are the issues with your current approach:
The lock object is not called lock or similar. (Yes ... a nitpick)
The variable is not final. If something accidentally (or deliberately) changes obj, your synchronization will break.
The variable is public. That means other code could cause problems by acquiring the lock.
I imagine that some of these effects are at the root of your critique: "this seems like bad coding to me".
To my mind, there are two fundamental problems here:
You have a leaky abstraction. Publishing the lock object outside of "class 1" in any way (as a public or package private variable OR via a getter) is exposing the locking mechanism. That should be avoided.
Using a single "global" lock means that you have a concurrency bottleneck.
The first problem can be addressed by abstracting out the locking. For example:
someMethod() {
Class1.doWithLock(() -> { /* code */ });
}
where doWithLock() is a static method that takes a Runnable or Callable or similar, and then runs it with an appropriate lock. The implementation of doWithLock() can use its own private static final Object lock ... or some other locking mechanism according to its specification.
The second problem is harder. Getting rid of a "global lock" typically requires either a re-think of the application architecture, or changing to a different data structures that don't require an external lock.
I often find myself with code like
private static final MyType sharedResource = MyType();
private static final Object lock = new Object();
...
synchronized(lock)
{
//do stuff with sharedResource
}
Is this really neccessary or could sharedResource be used as the lock itself like
private static final MyType sharedResource = MyType();
...
synchronized(sharedResource)
{
//do stuff with sharedResource
}
Note: synchronized blocks shown in the examples would live within methods doing work and are not methods themselves or synchronized methods.
EDIT: A very good point has been pointed out in some of the answers that if we are dealing with multiple shared resources that the first "Object" technique is far safer.
WARNING The fact that sharedResource is static is important! If it is static then synchronized methods or synchronized blocks locking on this won't work. The lock object must also be static.
Pros and cons of both
First option pros: Allows locking on concept, not on Objects. If you had to lock on multiple resources for a single action (which is usually not advised, but sometimes necessary) you could do this with much less worry about race conditions.
cons: The object could still be modified, so you need to ensure access to the object is restricted to methods that abide by the external lock.
Second option pros: Lock on the object should prevent others from modifying it (although you should double check the exact symantics.) EDIT: Has the same con as above - if the methods aren't synchronized internally, you could still run into methods that don't abide by the contract.
cons: You block access to all methods, even those unrelated to what you're trying to operate, which could cause slowdowns and possibly deadlock. You could easily make the case, however, that if that's the case your Object is doing too much work and should be broken up.
EDIT: Allow me to clarify part 2 here (the case to break up MyType into MyFoo and MyBar is open for debate...)
class MyType {
Foo foo;
Bar bar;
void doFoo() { foo.do(); }
void doBar() { bar.do(); }
}
class MyActions {
MyType thing;
void lotsOfFoo() {
// blocks bar :-(
synchronized(thing) { thing.doFoo(); }
}
void lotsOfBar() {
// blocks foo :-(
synchronized(thing) { thing.doBar(); }
}
}
Personally, I use option 1 much more often (that's why I'm unsure about that part in option 2).
The only problem I see, with using sharedResource as a lock if MyType has methods defined as synchronized itself. In this case, some strange behaviour my occur that was not intended by the developers of MyType. (See glowcoder's comment for an example.)
Otherwise it should be fine, however if you do only need one lock anyway, then just synchronize on this instead of introducing an additional dummy object.
Btw, did you itentionally make your lock object static? Because this means that all instance lock on the same monitor, i.e. they can block each other, which may not bee the behaviour you intended.
Yes, you can absolutely do that.
In fact it improves clarity and reduces clutter.
If I remembered right, synchronized is a monitor, it grants that only one thread can access that object at any given time in the same JVM. So I think you are only accessing shardResouce, synchronizing on the shardResouce is sufficient.
Personally, I don't usually synchronize on an arbitrary lock. That is, I'd usually do something along the lines of your second approach:
private static final MyType sharedResource = MyType();
...
synchronized(sharedResource) {
//do stuff with sharedResource
}
Of course, before running synchronized code, the lock for the target object must be obtained. Often, I take the locking "down" a step further, so to speak. Meaning, I would synchronize on a method within "sharedResource." As in:
public class MyType {
public void synchronized doWork() {
}
}
But when it comes to this kind of thing, it's hard to make generalizations because there are exceptions to every rule. In the end, your overall architecture requirements will dictate where your locking should occur. For me, most often, I find myself synchronizing the top-level method that accesses the shared resources and it is thereby more rare to lock on an object who does nothing more than serve as a lock.
EDIT: minor grammar fixes
While discussing a Java synchronization question, someone made a comment that the following snippets are not equivalent (and may compile to different bytecodes):
public synchronized void someMethod() {
//stuff
}
and
public void someMethod() {
synchronized (this) {
//stuff
}
}
Are they equivalent?
They are equivalent in function, though the compilers I tested (Java 1.6.0_07 and Eclipse 3.4) generate different bytecode. The first generates:
// access flags 33
public synchronized someMethod()V
RETURN
The second generates:
// access flags 1
public someMethod()V
ALOAD 0
DUP
MONITORENTER
MONITOREXIT
RETURN
(Thanks to ASM for the bytecode printing).
So the difference between them persists to the bytecode level, and it's up to the JVM to make their behavior the same. However, they do have the same functional effect - see the example in the Java Language Specification.
It should be noted, that if the method is overridden in a subclass, that it is not necessarily synchronized - so there is no difference in that respect either.
I also ran a test to block a thread trying access the monitor in each case to compare what their stack traces would look like in a thread dump, and they both contained the method in question, so there is no difference there either.
I made the original comment that the statements are identical.
In both cases, the first thing that happens is that the calling thread will try to acquire the current object's (meaning, this') monitor.
I don't know about different bytecode, I'll be happy to hear the difference. But in practice, they are 100% identical.
EDIT: i'm going to clarify this as some people here got it wrong. Consider:
public class A {
public synchronized void doStuff()
{
// do stuff
}
}
public class B extends A {
public void doStuff()
{
// do stuff
// THIS IS OVERRIDE!
}
}
In this case doStuff() in class B still overrides doStuff() in class A even though it is not synchronized.
Synchronized keyword is never part of the contract! Not for subclasses, not for interfaces, not for abstract classes.
I made the original comment. My comment was that they are logically equivalent, but compile to different bytecode.
I didn't add anything else to justify it at the time because there's not much to justify really-- they just do compile to different bytecode. If you declare a method as synchronized, then that synchronization is part of the method's definition. A synchronized block within a method isn't part of the method's definition, but instead involves separate bytecodes to acquire and release the monitor, as one of the posters above has illustrated. Strictly speaking, they're slightly different things, though to the overall logic of your program, they're equivalent.
When does this matter? Well, on most modern desktop VMs, hardly ever. But for example:
a VM could in principle make optimisations in one case but not the other
there are some JIT compiler optimisations where the number of bytecodes in the method is taken as a criterion for what optimisations to make
a VM without a JIT compiler (admittedly few nowadays, but maybe on an older mobile device?) will have more bytecodes to process on each call
Yes. Using the synchronized keyword on an instance method uses 'this' as a monitor ,also using it on a class method (static method) uses the class' Class object (Foo.class).
This way you can synchronize entire methods, and in the same time, synchronize it with a code snippet in another method using the synchronized-block style.
I can't see any functional difference - both synchronize their entire method bodies on (this). How did the person who commented that these are different justify their statement?
They are not quite equivalent in function. Other code could use reflection to see if your method has the synchronized modifier, but there is no way to tell if a method contains a synchronized block without reading its bytecode.
The ability to determine if a method is synchronized occasionally comes in handy. Personally, I've used that flag to avoid redundant locking when doing synchronization in aspect-oriented programming.
MyObject myObjectA;
MyObject myObjectB;
public void someMethod() {
synchronized (this) {
//stuff
}
}
public void someMethodA() {
synchronized (myObjectA) {
//stuff
}
}
public void someMethodB() {
synchronized (myObjectB) {
//stuff
}
}
In this case:
someMethod blocks entire class
someMethodA blocks myObjectA only
someMethodB blocks myObjectB only
someMethodA and someMethodB can be invoked at the same time