Code Sample 1:
class Test {
MyObj myObj = new MyObj();
public void test() {
// doing my other stuff
synchronized (myObj) {
// accessing myObj
}
}
}
Code Sample 2:
class Test {
MyObj myObj = new MyObj();
public void test() {
synchronized (myObj) {
// doing my other stuff
// accessing myObj
}
}
}
Code Sample 3:
class Test {
MyObj myObj = new MyObj();
public synchronized void test() {
// doing my other stuff
// accessing myObj
}
}
I want to keep thread safe to myObj in above code snaps. So which of above code snap is more preferable and Why?
code sample 1 is appropriate.
because holding the lock on object and then doing some other stuff is not appropriate.
according to codes that i have seen in Open Source Projects, The 1st code sample is better,because when you do not need object any more you release it so other threads can access it.
None of your examples contains enough information.
Where is the data? What are the invariants? When/Where/How do threads access the data?
"Thread safety" means nothing without data. The documentation for a stateful class usually will provide guarantees about how its methods will advance the state of an instance. "Thread-safe" means that those guarantees will be met even when the methods are called by many threads. But if the class is not stateful, or if there are no such guarantees, then "thread-safe" means nothing.
P.S.: Code Sample 1 has one important advantage over the others: The mutex (i.e., the synchronized block) is smaller. As a rule of thumb, you want your mutexes to be as small as possible. If "my other stuff" does not care about the data that are protected by the mutex, then it should not happen in the mutex because that would block other threads from accessing the data, and it would block them for no useful reason.
P.P.S.: +1 for #Ordous's comment: There is no way to know whether some object's state is thread-safe or not unless you can see every block of code that can modify or examine the state. Since myObj is not private in your example, we must assume that there is code elsewhere that could modify or examine its state. Since we can't see that code, we must assume that myObj is not thread safe.
Holding a lock on whole method (if it's long) is very costly. Not only it could block whole threat, but also it blocks code that does not need to be synchronized. Secondly sometimes you may not use your omyObj, in such cases example 2 and 3 would be bad.
To be short: synchronize only part of block, where you are working with your object. You can also use volatile on your object, to check for it's value, without synchronize block. Remember locking can be costly.
But when your method is short enough, or contains only code with myObj, then making whole method synchonized is a good solution.
public void test() {
// doing my other stuff, not concernign myObj
synchronized (myObj) {
// do things with myObj (read/write)
}
// doing my other stuff, not concernign myObj
}
Look at this singleton example.
Related
I am trying to synchronize read write operations on xml file from multiple methods in multiple classes. To achieve this, I am synchronizing this operations by using class level lock.
Code sample:
Test1.java:
public class Test1 {
public void method1() {
synchronized(CommonUtility.class) {
SomeObject someObject = testDAO.readSomething();
.
.
.
testDAO.writeSomething(someObject);
}
}
}
Test2.java
public class Test2 {
public void method2() {
synchronized(CommonUtility.class) {
SomeObject someObject = testDAO.readSomething();
.
.
.
testDAO.writeSomething(someObject);
}
}
}
To achieve this class level lock, consider following sample code:
synchronized(CommonUtility.class) {
.
.
.
}
What are the impacts of using Object.class instead of CommonUtility.class, like:
synchronized(Object.class) {
.
.
.
}
I think both approaches aren't ideal.
First of all, this here suggests:
You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class.
In other words: when you use synchronized(CommonUtility.class) you implicitly get "synchronized" with all static synchronized methods within CommonUtility. And worse: imagine that class has no such methods today. But next week, someone adds such a static synchronized method in that utility class, assuming that only calls to that method go through that monitor. Worst case, that could lead to some ugly (runtime only) surprises.
Then: going for even broader scope (by using Object.class) makes things worse.
My answer: avoid using class objects in the first place.
IMO, the idea of "class level" lock and "object level" lock is distracting. There is only one underlying synchronization mechanism in Java: synchronized (o) { ... } where o can be any Java object (Note that in Java MyClass.class is an object.)
When you write,
synchronized SomeType foobar(...) { ... }
That's really just a shortcut way of using an instance as the lock object that protects its own member variables.
SomeType foobar(...) {
synchronized (this) {
...
}
}
Same goes for so-called "class level" locking: It's just a shorthand way of using the class itself as the lock object that protects its own static members.
Speaking of which...
Good practice keeps the lock object near the data that it protects (for some definition of "near"). If the data are private, then the lock object ought to be private. If the data are members of some instance, then the lock object ought to be members of the same instance, etc.
Object.class isn't particularly "near" anything. It will work as well as any other object, but using it makes your code harder to understand, because the reader will spend time wondering what motivated you to choose Object.class, and wondering whether your choice was based on a misunderstanding.
My own preference, for protecting instance members, looks like this:
class MyClass {
private final Object lock = new Object();
private SomeType someVariableThatNeedsProtection = ...;
private SomeOtherType someOtherVariableThatAlsoNeedsProtection...;
...
public ... foobar(...) {
synchronized(lock) {
...
}
}
}
And, If I need to protect static members:
...
private static final Object lock = new Object();
...
The lock variable is private, just like the data it protects. Nobody who wants to understand your code will need to spend any time searching for anything else that is protected by the same lock object because they know it can't be accessed from outside of the MyClass methods.
The lock variable also is final. That will save readers from having to examine your code to make sure that it's always the same object that gets used as the lock. (Hint: if you think you need to be able to assign the lock variable, then you are either doing something that's sophisticated beyond the comfort level of many programmers, or you are making a bad mistake.)
I am trying to synchronize read write operations on XML file from multiple methods in multiple classes. To achieve this, I am synchronizing this operation by using class level lock.
That is not a good idea. You should have a single class (maybe XmlHelper) which manages the XML file and does the locking. XmlHelper would be used in the multiple methods in multiple classes and would control the locking on the file instead of multiple classes having to worry about it. That's much better object design.
Maybe something like:
public class XmlHelper {
public XmlHelper(File xmlFile) {
public synchronized SomeObject readSomething() { ... }
public synchronized void writeSomething(SomeObject someObject) { ... }
}
Then your Test1 and Test2 classes must share the same instance of the XmlHelper class so their locks will block each other. Instance level locks aren't always a great idea again because locks should be as fine-grained as possible, but it is fine in your application since the XmlHelper is designed for multiple classes to lock their IO operations.
What are the impacts of using Object.class instead of CommonUtility.class, like:
As others have mentioned, locking on the class is the same as calling a synchronized static method. This pattern should be used very sparingly since the lock is so coarse grained. What if your program needed to read/write to 2 XML files at the same time? Your class level lock would cause IO operations to the 2 files block each other -- not optimal.
If you locked on Object.class then any other class which happens to be doing the same lock will block your threads unnecessarily. God help you.
A race condition is getting hit. For example: thread1 reads file contents and updates read contents. Before thread1 writes back to file, thread2 reads content. Then thread1 writes updated contents to file. And at last thread2 writes content to file. This is leading to contents loss,
There are a couple of ways of doing this. You could have some sort of update method on your XmlHelper class:
public synchronized void updateObject(...) {
SomeObjecto obj = readSomething();
// adjust object here based on the arguments
writeSomething(obj);
}
If each of the threads need to do their own updating then they will need to lock externally on the same object. I recommend locking on the shared instance of the XmlHelper.
synchronized (xmlHelper) {
...
}
The locking on the class object will work but it is far to big a hammer to be recommended. Again, if you have 2 instances of the XmlHelper working on 2 different files, you would not want IO operations on 2 different files to block each other.
I have seen this NullPointerException on synchronized statement.
code:
synchronized(a){
a = new A()
}
So according to the above answer I have understood that it is not possible to use synchronized keyword on null reference.
So I changed my code to this:
synchronized(a = new A()){}
But am not sure if this is identical with my original code?
update:
what I want to achieve is lock the creation of a ( a = new A() )
Synchronized requires an object that will provide locking mechanism. It can be any object (in fact, synchronized without parameters will synchronize on this), but Java API provides classes dedicated to this functionality, for example ReentrantLock.
In code you provided every call to function containing synchronized block will use different object for locking, effectivly making synchronization useless.
Edit:
Since you updated your post with what you are actually trying to accomplish I can help you more.
public class Creator {
private A a;
public void createA() {
synchronized(this) {
a = new A();
}
}
}
I don't know if this fits your design since the code sample you provided is very small, but you should get the idea. Here instance of the Creator class is used to synchronize the creation of A. If you share it across multiple threads, each one of them calling createA(), you can be sure that one instantiation process will be finished before another one begins.
synchronized(a = new A()){}
so what it will do is it will create a new object of class A and use
that as Lock, so in simple word every thread can enter in synchronized
block anytime because each thread will have new lock and there will be
no other thread that is using that object as lock so every thread can
enter your synchronized block anytime and outcome will be no
synchronization
For Example
class TestClass {
SomeClass someVariable;
public void myMethod () {
synchronized (someVariable) {
...
}
}
public void myOtherMethod() {
synchronized (someVariable) {
...
}
}
}
here we can say Then those two blocks will be protected by execution
of 2 different threads at any time while someVariable is not modified.
Basically, it's said that those two blocks are synchronized against
the variable someVariable.
But in your case there will be always a new object so there will be no synchronization
These two code snippets are not equivalent!
In the first code snippet you synchronize on some object referenced by a, and afterwards you change the reference which will not change the synchronization object.
In the second snippet you first assign a newly created object to reference a and then synchronize on it. So the synchronization object will be the new one.
Generally, it is a very bad idea to change the reference which is used in the synchronized statement, regardless whether it is done inside the block (first code) or diretcly in the synchronized statement (second code). Make it final! Oh, and it mustn't be null, either.
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 was wondering if there is a situation where this statement will be true and needed. All the examples I have seen only synchronize on the "this" reference. Can someone tell me how a block of code in one object can be synchronized on any other reference apart from this ?
Yes the statement is true.
There are several reasons why one would want NOT to use an intrinsic monitor (synchronized(this)) - one of these reasons is that it can create liveness issues - in the code below, B uses an instance of A as a lock, maybe to control access to that variable. If another thread uses that same instance of A and tries to run a.methodA(), it will be blocked until methodB() is over.
So using an intrinsic monitor exposes the synchronization policy and can lead to subtle bugs and performance issues.
public class A {
public synchronized void methodA() {}
}
public class B {
A a = new A();
public void methodB() {
synchronized(a) {
// do something a little long
}
}
public A getA() {return a;}
}
If A had used an internal monitor that problem would not be possible.
public class A {
private final Object lock = new Object();
public void methodA() {
synchronized(lock) {}
}
}
Another scenario where using ad hoc monitors makes sense is when a class contains 2 (or more) unrelated objects, that both need to be accessed in a synchronized manner. Using 2 monitors instead of one reduces contention as the 2 objects can now be accessed concurrently.
public class SyncTest{
private Object obj = new Object();
public void func1() {
synchronized(obj) {
obj.something();
}
}
Yes it can be done.
The synchronize block will use that object as a lock, rather than the whole class. People that use synchronized(this) { } put an exclusive lock on the whole object, which might be what you want. However, you might have something like a persister, which is the only thing that needs to be synchronized. synchronized(persister) { }, would provide a less granular way of doing this.
In Java, you can use synchronized constructs to create instrinsic locks on any object reference, yes. Read the relevant Java Tutorial.
The immediate example of not using synchronized with this is when synchronizing on the Class object, which is how static synchronized methods work. In reality, there are plenty of valid uses. You may want to avoid using synchronized (this) in favor of an internal implementation lock as otherwise you are setting a restriction that you use the lock internally, which other code you're not aware of might violate.
You should know, however, that often times you can replace synchronized usage with a ReentrantLock. You can read more about this in my post here.
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