What is the difference or impact between using the synchronized block as in method1 and method2?
class A
{
private Object lock = new Object();
...
...
private void method1()
{
synchronized(A.class)
{
.....
}
}
private void method2()
{
synchronized(lock)
{
....
}
}
}
In first method all threads that use ANY instance of the class A will be syncronised.
In second method all threads that use THIS instance of the class A will be syncronised.
Since A.class is avaliable to others, it is public in effect. If something else uses it to synchronize access to some section of code then your section of code could be blocked. This might be good or bad; but you don't have control over it.
Using an internal object allows you to decare it as private so that you have complete control over where and when it is used. I prefer to use an internal object that I have control.
Lock is an ordinary field. So there is one of it for each instance of 'A'. A.class is global to the whole JVM. So the two blocks have completely different semantics. The version with 'lock' says, 'only one thread can be in this block for this instance of A'. The version with A.class says 'only one thread can be in this block for any instance of A.
In the first case, you synchronize on a public object (A.class), and so other parts of the application might cause problems because they also synchronize on A.class.
In the second case, you synchronize on a private lock object, and are thus sure that nobody else uses the the lock to synchronize access to something else.
Moreover, as indicated in other answers, all the instances of the class will be synchronized on the same lock with the first solution, whereas each instance will have its own lock with the second solution.
The second solution is thus much preferred (although the lock object should be final).
The parameter of synchronized block is needed to be able to create several "named" blocks. So using special lock object is probably more flexible: you can create lock1 and lock2 in future.
Yet another aspect is waiting and notification. You can say lock.wait() and then lock.notfify() from another thread. In this case you can also use both ways (special lock object or A.class as a lock).
Related
Why do you have to specify, which object has locked a synchronized block of code?
You don't have to specify which object has locked a synchronized method as it is always locked by 'this' (I believe).
I have two questions:
Why can't you block a none static method with an object other than
'this' ?
Why do you have to specify the object that has blocked
synchronized code?
I have read chapter nine of SCJP for Java 6, but I am still not clear on this.
I realize it is probably a basic question, but I am new to Threading.
Why can't you block a none static method with an object other than 'this' ?
You can:
public void foo() {
synchronized (lock) {
...
}
}
Why do you have to specify the object that has blocked synchronized code?
Because that's how the language designers chose to design the language. synchronized, when used on instance methods, implicitely uses this as the lock. synchronized when used on a block must explicitely specify the lock.
You can.
The code
synchronized foo() {
// some stuff
}
Is logically equal to code
foo() {
synchronized(this) {
// some stuff
}
}
I said "logically" because these 2 examples generate different byte code.
If method foo() is static synchronization is done of class object.
However you can wish to create several synchronized blocks that are synchronized on different objects into one class or even into one method. In this case you can use synchronized (lock) where lock is not this:
foo() {
synchronized(one) {}
///..........
synchronized(two) {}
}
You can specify any object you want which should have the lock on the synchronized code block. Actually, you shouldn't use synchronize(this) at all (or maybe be careful about it, see Avoid synchronized(this) in Java?).
EVERY object has a lock on which you can synchronize:
final Object lock = new Object()
synchronized ( lock ) { ... }
If you want to synchronize the whole method, you cannot say on which object, so it is always "this" object.
synchronized foo() {....}
The first way of locking is better, by the way.
It is not recommended to lock each method with this as it reduces the concurrency in most cases. So it is recommended to use Lock Stripping in which only the specific part of the code that needs to be protected is kept in synchronized block.
It is a practice that is explained well in Java Concurrency in Practice. But note this book is useful only when you have some basic experience with threading.
Some nuggets to keep in mind:
Do not overuse synchronization
use method level synchronization only when the whole method needs to be protected
Use different locks to protect two unrelated entities, which will increase the chances of concurrency. or else for reading or writing two unrelated entities threads will block on same lock.
public void incrementCounter1(){
synchronized(lockForCounter1){
counter1++;
}
}
public void incrementCounter2(){
synchronized(lockForCounter2){
counter2++;
}
}
I think your two questions actually are same. let's say if you wanna synchronized a method m of object a between multiple threads, you need a common base system or channel that threads can talk to, this is actually what object lock offers, so when you wanna a method of a object be synchronized there is no need for another object lock to do this, because the object you access itself has this lock, that's how and why lanuage designed.
while synchronized a block is not the same thing, threads can have different talking base other than this object itself, for instance, you can set a same object as synchronized object lock for synchronized block, so all objects of this Class can be synchronized at that block!
From the concurrency tutorial, the Synchronized methods part:
To make a method synchronized, simply add the synchronized keyword to its declaration:
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
If count is an instance of SynchronizedCounter, then making these methods synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
Simply put, that's how synchronization in Java works.
You don't have to specify which object has locked a synchronized method as it is always locked by 'this' (I believe).
True for instance methods, for static methods it locks upon the class object.
Why can't you block a none static method with an object other than 'this' ?
Note that:
public synchronized void increment() {
c++;
}
is equivalent in behavior to:
public void increment() {
synchronized(this) {
c++;
}
}
In this code snippet you can replace this with any object you wish.
Why do you have to specify the object that has blocked synchronized code?
Some, let's call it critical, block of code is to be ran only sequentially, but in uncontrolled concurrent environment it is possible that it will be ran in parallel. That's why synchronization mechanisms exists.
So we can divide the code like this:
the code safe to be ran in parallel (default situation)
the code that has to be synchronized (must be marked somehow)
That markation is made via the synchronized keyword and the corresponding lock object.
If you have two different critical code blocks that must not be ran together, they'll both have the synchronized keyword, and let's say they have the same lock object.
While the first block is executing, the lock object becomes "locked". If during that time the second block needs to get executed, the first command of that code block is:
synchronized(lock) {
but that lock object is in locked state because the first block is executing. The execution of the second block halts on that statement until the first block finishes the execution, and unlocks the state of the lock object. Then the second block may proceed with the execution (and lock the lock object again).
That mechanism is called the mutual exclusion and the lock is a general concept not tied to the Java programming language.
The details of the "lock object locking" process can be found here.
You can lock with any instance of an object but programmers usually
use this or locker...
Because it restrict access to that part of code by other threads
(unit of code processing) so you make sure whole of that part run in
consistence and nothing (i.e. a variable) would be alerted by another thread.
Consider:
a = 1;
a++;
Thread one reaches second line and you expect a = 2 but another thread executes first line and instead of 2 you have a = 1 for first thread and a = 2 for second thread. Now:
synchronized (whatever)
{
a = 1;
a++;
}
Now second thread would be blocked from entering into the code block (synchronized body) until first one leaves it (release the lock).
One of my textbook mentions that the argument of synchronized() must be this... I know it is wrong. But I heard that since synchronized(this) is safer, one should always use it. Is that true ?
Thank you:)
No it does not have to be always this. Also it simply cannot be in the case of static methods, because there is no this.
Also it is sometimes considered wrong to synchronize to this, because then lock object is visible outside.
public class Example {
private final Object lock = new Object();
// does not compile, there is no 'this' in static context.
public static void staticMethod() {
synchronized (this) {
}
}
public void method() {
int x = 3;
//there is risk that someone else outside our code
//uses same lock
synchronized (this) {
}
//this lock is private
synchronized (lock) {
}
}
}
One of my textbook mentions that the argument of synchronized() must be this... I know it is wrong.
That is incorrect. Either the textbook is incorrect, or you have misunderstood it. The Java language allows you to synchronize on any (non-null) object reference.
But I heard that since synchronized(this) is safer, one should always use it. Is that true?
No that is not true either. It is not safer, and you certainly shouldn't always lock on this.
In fact if you are writing a general purpose library class that needs to lock "itself", it is often a good idea to declare a private lock field; e.g.
private final Object myLock = new Object();
... and lock that object rather than this. This eliminates the kind of problems that can occur is some external code decides to lock the library object for some reason, leading to unwanted contention, and possibly deadlocks between the library classes methods and the external code.
I suspect that the point that the textbook was trying to make is that all methods that are using primitive locks to give mutual exclusion and synchronization on a data structure must use the right object as the lock. This isn't necessarily the data structure object itself, but it does need to signify that object ... in some sense. (If you don't lock the object that signifies the data structure, you risk having one thread not excluding others while it uses / updates the data structure.)
Here is a sketch of the problem that private locks aim to avoid.
/** This class implements thread-safe getting / setting by synchronizing on 'this' */
public class IntHolder {
private int value;
public int getValue() {
synchronized(this) { return value; }
}
public void setValue(int value)
synchronized(this) { this.value = value; }
}
/* Somewhere else, some other code (the "external code") used a holder instance
as the lock for some larger-scale synchronization. */
IntHolder h = ...
synchronized (h) {
/* Do something that takes a long time ... */
}
The problem is that while the external code holds that lock on h, other threads won't be able to read or change the holder's value. If that was intended ... that is fine. However, if the thread-safety of the IntHolder type is intended to be "just an implementation detail" you now a potentially unexpected failure case.
IMO you're better off using 'volatile' and 'synchronized' on fields and methods if you're unsure whether synchronized(this) is a good idea in that particular place.
to put it simply, volatile places an intrinsic mutex on a variable; synchronized places an intrinsic mutex on a function call; synchronized block places an intrinsic mutex around that piece of code locked by the parameter.
Usually you'd make a lock and lock on a Object, but sometimes you want to lock on the instance itself... though, I'd advise caution on locking with a whole class instance if you only need access to one of it's members/fields (something you could've solved using synchronized and volatile in the first place)
The real reason why you might want (or not want) to lock on this is scope of the lock, you can see the lock if you lock on this. if you init a private object, the lock is hidden away.
The argument of synchronized is simply which object the hold will be placed on. It depends on what you want to do in the synchronized block that will determine what the argument should be. Using this puts a hold on the current object.
As a personal anecdote, in the project I'm currently working on, all of my synchronized holds are on COM ports, so that there's no collisions between sending and receiving packets
it doesn't matter which lock you use. Every java.lang.Object can act as a lock. You have to make sure that all operations that work on the same mutable state use the same lock.
so synchronized(this) is exactly as safe as
private final Object lock = new Object();
synchronized(lock)
If you declare a non-static method as synchronized:
public synchronized void doSomething()
{
...
}
then it is synchronized on this. So if your goal is for a synchronized block to be synchronized with synchronized non-static methods like the above, then you do need to use synchronized(this).
But you are correct: you can also write synchronized(someOtherObject), as long as you're aware that that will lock out synchronized methods of someOtherObject rather than of this.
(For static methods, by the way, synchronized synchronizes on the Class instance representing the containing class.)
No , this is not necessary that you should use this .Even you an apply lock on any other object which not an instance of this.
synchronized(obj1){
-------
}
synchronized(obj2){
-------
}
In a single method you can write something like above where you first acquire the lock on some object obj1 and then did work and released and then acquire the lock on obj2.
Aaah, the infamous Avoid synchronized(this) in Java?.
There is, actually, no difference between
public synchronized void doThis() {
}
and
public void doThis() {
synchronized (this) {
}
}
Except on the bytecode level. Both address thread-safety. They both pose a problem as you can potentially introduce deadlock, if (for example, you set a lock of the same class, within its synchronized block).
If you're worried about deadlock, then a dedicated lock should be used, like so:
public class MyClass {
private final Object lock = new Object(); //Must be final
public void doThis() {
synchronized (lock) {
}
}
}
Alternatively, use the Java java.util.concurrent.Lock interface and the java.util.concurrent.locks.ReentrantLock implementation to do basically lock..
I'm not used to working with synchronized. Does the following snippet look right?
public void setNewSessionListener(NewSessionListener newSessionListener) {
if (this.newSessionListener != null)
synchronized (this.newSessionListener) {
this.newSessionListener = newSessionListener;
}
else
this.newSessionListener = newSessionListener;
}
More specifically do I need to perform a null check? I have a gut feeling there is something fundamentally wrong with that code.
There are two mistakes. The first one is that if you access a field which requires synchronization, you always have to access it with the same lock held. Also you have to check if the field is null and write to the field in the same sychronized block, because otherwise when you write something to the field, it may already be not null.
The second one is that it is best to sychronize on something that doesn't change, in other words, on a static final field or on the instance itself. For example, you can create a lock object specifically for this purpose:
private static final Object LOCK = new Object();
And then you will write:
synchronized (LOCK) {
if (this.newSessionListener == null) this.newSessionListener = newSessionListener;
}
Your feeling is right. You should do the null check inside the synchronized block. Otherwise the block won't prevent double initialization. Furthermore, you shouldn't synchronize on this.newSessionListener which you are about to change - choose an object (reference) which is going to stay around for the whole scope of the block. This is the only way to guarantee that only one thread can enter this block of code at any point in time. The typical way to achieve this is to synchronize on this. Alternatively, you may synchronize on a private final object, kept for this sole purpose.
Moreover, ultimately you are performing the same assignment in both the if and the else branches, which is probably not what you want.
This is, at a minimum, a very bad idea. You are synchronizing on an object you then assign to.
Because you are using synchronized I assume this is called asynchronously and it could be called by one thread while another thread is inside this code. If so, you are not locking on a common object, you are locking on the value it is holding at that point in time.
Probably, and I stress probably, you can do synchronized (this). That will insure that all calls to this method for this specific object are synchronized. And that calls to other instances of this class are locked for that other object - but not across instances.
If you want to synchronize across all instantiated objects, call synchronized (YourClass)
Here's another possibility (i tend to prefer explicit locks over the synchronized block):
private ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// do your synchronized code here.
}
finally {
lock.unlock();
}
Though just by looking at your code, i'm not sure why there's even an if block. Why are you synchronized in one case, and not the other? Especially considering you're making the same assignment in either case?
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.
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).