Synchronization in Java? - java

I am pretty new to thread-safe programming, and was wondering if I have something like below, would this be safe from deadlock once compiled and run?
public class Foo
{
protected CustomClass[] _mySynchedData = new CustomClass[10];
public void processData()
{
synchronized(_mySynchedData) {
// ...do stuff with synched variable here
}
}
}
public class Bar extends Foo
{
#Override
public void processData()
{
synchronized(_mySynchedData) {
// perform extended functionality on synched variable here
// ...then continue onto parent functionality while keeping synched
super.processData();
}
}
}
Bar testObj = new Bar();
// Deadlock?
testObj.processData();

Your code only display a single thread.
With only one thread, there's no way you can get any deadlock.
Added:
Java language supports what they officially call reentrant synchronization.
It basically means that a single thread can reacquire a lock it already owns.

Your question is what happens when you synchronize two times on the same object.
The answer is: Java will check first which thread owns the monitor (that's the internal data structure on which synchronized operates). Since the owner thread is the same as the current thread, Java will continue.
Deadlocks can only happen if you have two monitors and you try to lock them in different orders in different threads.

The lock taken by the Java synchronized keyword supports nesting, so you don't risk a deadlock by synchronizing on the same object multiple times in the same thread.

RichN is correct in that your code only contains a single thread and hence deadlock is impossible. Also note that for a deadlock to occur you need to have multiple threads acquiring multiple locks (albeit in a different order) for a deadlock to occur.
Your code currently only references one lock: The one associated with _mySynchedData. The fact that you attempt to lock it twice does not matter as locks in Java are reentrant.

Related

How is this lock useful anyway?

I am relatively new to concurrency. I am practicing concurrency from Oracle website. I am stucked at the following example:-
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
I want to know how is this type of lock useful over using synchronized(this) type lock? And in which situations should this type of lock be preferred?
Thanks
It's useful when you have a single object that needs a finer resolution of exclusion than the object itself. In other words, an object with multiple resources that need to be protected but not necessarily from each other.
Being bought up in the pthreads world, this is easy to understand since the mutex and it's protected resource tended to be always decoupled - there was never this handy shorthand found in Java for using an object as the lock.
As an example, say each object has a array of a thousand integers and you want to lock a group of a hundred at a time (0xx, 1xx, and so on) for maximum concurrency.
In that case, you create ten objects, one per group of a hundred, and you can lock individual parts of the array. That way, if you have a thread fiddling about with the 0xx and 4xx blocks, it won't stop another thread from coming in and doing something with the 7xx block.
Now that's a pretty contrived example but the concept does occasionally show up in reality.
In the specific example you've given, only one thread at a time can come in and increment c1 concurrently, but a lock on lock1 still permits another thread to come in and change c2.
With a object (this) lock, concurrency would be reduced because c1 and c2 couldn't be updated concurrently despite the fact that there is no conflict.
Object lock is nothing but you are locking the critical section explicitly by an object. synchronized (this) describes that you are locking the critical section by the current object.
Having two separate locks for inc1 and inc2 is useful in situations where you want to make sure that no two concurrent threads can both call the same method at the same time, but where you do want to allow two concurrent threads to call different methods on the same object.
In your example, if thread 1 calls inc1, thread 2 is blocked from calling inc1 until thread 1 is done. However, thread 2 is free to call inc2.

synchronized(this) blocks whole object? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
synchronized block vs synchronized method?
From accepted answer to this question: In Java critical sections, what should I synchronize on?
I learn that
public synchronized void foo() {
// do something thread-safe
}
and:
public void foo() {
synchronized (this) {
// do something thread-safe
}
}
do exactly the same thing. But in first case we make synchronized only one method of object, and in second case we make inaccessible Whole object. So why this two code snippests do same things?
You seem to be mixing things.
Firstly
public synchronized void method() {
}
is equivalent, from a synchronization perspective, to:
public void method() {
synchronized (this) {
}
}
The pros / cons have already been mentioned and the various duplicates give more information.
Secondly,
synchronized(someObject) {
//some instructions
}
means that the instructions in the synchronized block can't be executed simultaneously by 2 threads because they need to acquire the monitor on someObject to do so. (That assumes that someObject is a final reference that does not change).
In your case, someObject happens to be this.
Any code in your object that is not synchronized, can still be executed concurrently, even if the monitor on this is held by a thread because it is running the synchronized block. In other words, synchronized(this) does NOT "lock the whole object". It only prevents 2 threads from executing the synchronized block at the same time.
Finally, if you have two synchronized methods (both using this as a lock), if one thread (T1) acquires a lock on this to execute one of those 2 methods, no other thread is allowed to execute any of the two methods, because they would need to acquire the lock on this, which is already held by T1.
That situation can create contention in critical sections, in which case a more fine grained locking strategy must be used (for example, using multiple locks).
We don't synchronize an object, instead we synchronize a block of code. In the first that block of code is the method itself, while in the second it's the synchronized block.
The object only provides the lock so as to prevent multiple threads from simultaneously entering that block of code. In the first case, the this object (the one on which the method is invoked) will be used implicitly as the lock, while in the second case it doesn't always have to be this object, it could be some other object also.
They do the same thing. The first form is a short-hand for the second form.
One minor difference between the two constructs is this - synchronized blocks are compiled into monitorenter (op-code 0xC2) and monitorexit (op-code 0xC3) instructions.
A synchronized method, when compiled, is distinguished in the runtime constant pool by
the ACC_SYNCHRONIZED flag, which is checked by JVM’s the method invocation instructions. This difference does not have much significance in practice though.
They dont do same things. First part being synched from beginning to end. Second is just synching the block(not whole method). Second one has some flexibility.

Synchronized threads and locking

Can someone please explain the difference between these two examples in the context of object locking:
public void method1(){
synchronized(this){
....
}
}
And
StringBuffer aStringBufferObject = new StringBuffer("A");
public void method2(){
synchronized(aStringBufferObject){
....
}
}
I know the first example will obtain a lock on the this instance and the second will obtain a lock of the aStringBufferObject instance. But i dont really understand what the effect or the difference of the two is.
For example, in the second example, will threads still be able to execute the code inside the synchronized block because the lock is not related to the 'this' instance?
I know that synchronizing a method or a block of code prevents multiple threads to access that block/method at the same time but what is the purpose of specifying the object to lock on and what is the difference in the way the object is specified as in the above examples?
What is the purpose of specifying the object to lock on?
Often, it is easier to synchronize on this or on the Class instance (for static methods). But, there are cases where you will need to synchronize on a specific object instead of the implicit lock (this). Such cases include:
You want to synchronize access to primitives without using this. You can only synchronize on Objects as each Object is associated with an implicit monitor in Java. Primitives do not have such implicit monitors, and therefore you need to use a lock object. Using the wrapper classes are a poor and incorrect choice, especially if you end up modifying the lock object in the guarded block.
You want to synchronize on an object that actually protects the critical section, when synchronizing on this would not offer a guarantee of thread safety. For instance, if you are synchronizing access to a ArrayList instance shared across instances of class A, then synchronizing on an instance of A is useless. A thread might create a new instance of A and gain access to the list, while another thread is modifying it. If you use a different lock that all threads must contend for then you can protect the list; this lock could be the one associated with A.class, but it could be any object that will offer the same guarantees.
You want to perform lock splitting to ensure that different guarded blocks are protected by different locks instead of the same lock. In other words, if it is thread-safe to allow different threads to acquire different locks to access different critical sections, then you can have a different lock for every critical section.
The following is an example of split lock usage:
private Object method1Lock = new Object();
private Object method2Lock = new Object();
public void method1(){
synchronized(method1Lock){
....
}
}
public void method2(){
synchronized(method2Lock){
....
}
}
You would use split locks when you can ensure that the concurrent execution of method1 and method2 do not violate the class invariants. This way, you can improve performance across threads that need access to the same object, but will be invoking different methods.
On your other question,
For example, in the second example, will threads still be able to execute the code inside the synchronized block because the lock is not related to the 'this' instance?
In the second example, any thread entering the guarded region must acquire the lock associated with aStringBufferObject. If a different thread is holding that lock, then the current thread will not proceed further. When you specify this, then the thread must acquire the lock associated with the current object. In both cases, a thread must acquire a lock; the examples are only different in the object that is being used as a lock.
Synchronizing on an object means that other blocks which synchronize on the same object will have to wait. For example:
public void methodA() {
synchronized(obj) {
//Do one job
}
}
public void methodB() {
synchronized(obj) {
//Do another job
}
}
If you call methodA() in one thread and then call methodB() in another thread, methodB() won't finish before methodA() finishes.
The synchronized block is a monitor, which leave out of details to lock and unlock a mutex. Because every object in Java has an internal lock(refer to source code of Object class), when use synchronized statement, the JVM will help you synchronize the critical section. You can also synchronize block yourself use ReentrantLock in package java.util.concurrent.locks.

Java synchronized methods question

I have class with 2 synchronized methods:
class Service {
public synchronized void calc1();
public synchronized void calc2();
}
Both takes considerable time to execute. The question is would execution of these methods blocks each other. I.e. can both methods be executed in parallel in different threads?
No they can't be executed in parallel on the same service - both methods share the same monitor (i.e. this), and so if thread A is executing calc1, thread B won't be able to obtain the monitor and so won't be able to run calc2. (Note that thread B could call either method on a different instance of Service though, as it will be trying to acquire a different, unheld monitor, since the this in question would be different.)
The simplest solution (assuming you want them to run independently) would be to do something like the following using explicit monitors:
class Service {
private final Object calc1Lock = new Object();
private final Object calc2Lock = new Object();
public void calc1() {
synchronized(calc1Lock) {
// ... method body
}
}
public void calc2() {
synchronized(calc2Lock) {
// ... method body
}
}
}
The "locks" in question don't need to have any special abilities other than being Objects, and thus having a specific monitor. If you have more complex requirements that might involve trying to lock and falling back immediately, or querying who holds a lock, you can use the actual Lock objects, but for the basic case these simple Object locks are fine.
Yes, you can execute them in two different threads without messing up your class internals but no they won't run in parallel - only one of them will be executed at each time.
No, they cannot be. In this case you might use a synchronized block instead of synchronizing the whole method. Don't forget to synchronize on different objects.

There is a easy way to protect a variable to be accesed only by one thread at once?

i have a variable on my "SharedPreferences", that is accesed by two different threads, one in a service, and one in a activity.
There is a easy way to protect this variable to be accesed by two threads at once?
i need to protect this code:
configEditor.putString("mylatitude", ""+currentLocation.getLatitude());
configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
configEditor.commit();
i tryed with this but doesn't works:
Object LOCK = new Object();
synchronized (LOCK){
configEditor.putString("mylatitude", ""+currentLocation.getLatitude());
configEditor.putString("mylongitude", ""+currentLocation.getLongitude());
configEditor.commit();
}
thanks
Object LOCK = new Object();
synchronized (LOCK) {
// lines of Java code that has to be thread safe
}
EDIT: edit the code to be exactly for the situation when the code is modifying several variables and it has to be thread-safe. For a single variable (as is in the title of the question) lock the variable itself, you don't need a separate lock for it.
I'm not sure, but I believe using a Handler may be what you need.
Take a look at this article, which explains when and how to use them. It also provides some code samples which may be helpful.
Try something like this:
public class MyClass {
private final Object lock = new Object();
public myMethod() {
...
synchronized (lock) {
// At most one thread is executing this
// at the same time for this instance
}
...
}
}
The important thing is that the lock object should be an instance (and not local) variable, so that every thread uses the same lock for that particular instance of MyClass. Most of the time you want it to be final so that there is no posibility of changing it by mistake.
If you make the lock static, then at most one thread will be executing the synchronized section, no matter in which instance of MyClass.
EDIT:
For your particular case, you can adapt the following idea:
public class Service {
public void doSomethingWithConfigEditor() {
ConfigEditor configEditor = // get configEditor
synchronized (configEditor) {
// something with configEditor
}
}
}
public class Activity {
public void doAnotherThingWithConfigEditor() {
ConfigEditor configEditor = // get configEditor
synchronized (configEditor) {
// another thing with configEditor
}
}
}
By synchronizing on configEditor, you guarantee that those two blocks of code never execute in parallel on the same instance of ConfigEditor.
This is typically done using critical sections aka mutexes. Before accessing the variable, your thread should aquire a lock on the mutex. While the mutex is locked, any attempt to aquire another lock will wait until the previous lock is released. This way, threads will wait for each other when accessing the variable.
You need to put the synchronized block in both locations that access the variable which you are trying to protect. Protecting it only one of the locations doesn't help.
Are you sure this is in two different threads? Your service code will only be running in a different thread if you are executing due to someone calling through to your IBinder interface from another process (or another thread in your own process).

Categories

Resources