Based on tutorials online, I have come up with below code of guarded suspension.
public synchronized String method1() throws InterruptedException {
lock = true;
Thread.sleep(17000);
lock = false;
notifyAll();
return "Method1";
}
public synchronized String method2() throws InterruptedException {
while(lock) {
wait();
}
Thread.sleep(3000);
return "From Method 2";
}
Above two methods are called at the same time from multiple threads.
From the above example, Does that lock variable used in the pre-condition for wait() ever be true ?
because with use of synchronized keyword, both methods are executed mutually exclusively.
Is the above example correct for Guarded suspension ?
When do we need Guarded Suspension ?
The Java keyword synchronized used on an instance method does ensure that only one thread at a time will execute any method on that single instance having the method modifier synchronized as well. More precise: not only on any method but on any resource / data using the same instance as a monitor or semaphore for mutual exclusively access control.
In your example, both instance methods have the modifier synchronized and hence will ensure only one thread is executing code inside any of those methods at any given time.
The variable lock is of no use in your example, because the same method which sets it to true does change it back to false. Hence method2 will never observe lock to be true.
Whenever more than one thread have to operate on a mutable resource and both threads should agree on the state read / operated, you have to protect this resource from racing conditions (read or modified concurrently). Otherwise the result may be different if executed by a single thread.
I think, your implementation is incorrect because you are doing lock = true; and lock = flase; in the same method.
In my opinion, it has to be done like below,
public synchronized String method1() throws InterruptedException {
Thread.sleep(17000);
lock = false;
notifyAll();
return "Method1";
}
public synchronized String method2() throws InterruptedException {
while(lock) {
wait();
}
Thread.sleep(3000);
lock = true;
return "From Method 2";
}
You have to understand that Guarded Suspension is a pattern when you have a situation where a precondition also needs to be satisfied in addition to synchronization lock being available.
e.g. when going to implement a thread-safe blocking queue, we need to put take() method thread on wait state if no items are available and put method thread also on wait state if queue is full. So this requirement is there in addition to synchronized access i.e. queue needs to be accessed in mutual exclusive way ( that is a primary requirement so you put synchronized on method signature ) but if queue is not in a proper state( by checking precondition variable) , you do wait or notify etc.
You have to also keep in mind that Thread.sleep(...) doesn't releases synchronization lock while Object.wait() does.
Take a real - life example ( like that of a thread - safe blocking queue ) then we can tell if your implementation is correct or not - its not possible to tell if your implementation is correct or not ( other than pointing that lock shouldn't be set / reset in same method ) since there is no generic implementation of this pattern.
Refer This
Hope it helps !!
Related
I can't understand the following code:
public class Counter {
private long value;
private Lock lock;
public long getAndIncrement() {
lock.lock();
try {
int temp = value;
value = value + 1;
} finally {
lock.unlock();
}
return temp;
}
}
What I can't understand is how Lock is instantiated while it's an interface?
And if it's an anonymous class that implements Lock interface, why I can't see any override of Lock functions (e.g. lock() and unlock() ) ?
In short, the following line really confuses me.
private Lock lock;
What is lock here? What is its type?
Edit:
Lock is an interface and can't be instantiated. After looking at the constructor:
public Counter(){
lock = new ReentrantLock();
}
Now, everything is clear. (Thanks to Bhushan Uniyal )
Q how Lock is instantiated while it's an interface?
Lock in an interface, implemented by ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock
From Java Doc
A reentrant mutual exclusion Lock with the same basic behavior and
semantics as the implicit monitor lock accessed using synchronized
methods and statements, but with extended capabilities.
A ReentrantLock is owned by the thread last successfully locking, but
not yet unlocking it. A thread invoking lock will return, successfully
acquiring the lock, when the lock is not owned by another thread. The
method will return immediately if the current thread already owns the
lock. This can be checked using methods isHeldByCurrentThread(), and
getHoldCount().
The constructor for this class accepts an optional fairness parameter.
When set true, under contention, locks favor granting access to the
longest-waiting thread. Otherwise this lock does not guarantee any
particular access order. Programs using fair locks accessed by many
threads may display lower overall throughput (i.e., are slower; often
much slower) than those using the default setting, but have smaller
variances in times to obtain locks and guarantee lack of starvation.
Note however, that fairness of locks does not guarantee fairness of
thread scheduling. Thus, one of many threads using a fair lock may
obtain it multiple times in succession while other active threads are
not progressing and not currently holding the lock. Also note that the
untimed tryLock method does not honor the fairness setting. It will
succeed if the lock is available even if other threads are waiting.
lock()
Acquires the lock.
Acquires the lock if it is not held by another thread and returns
immediately, setting the lock hold count to one.
If the current thread already holds the lock then the hold count is
incremented by one and the method returns immediately.
If the lock is held by another thread then the current thread becomes
disabled for thread scheduling purposes and lies dormant until the
lock has been acquired, at which time the lock hold count is set to
one.
Lock is a interface and you need to provide it implementation of Lock, there are already some classes which provide the implementation of Lock , ReentrantReadWriteLock.ReadLock, ReentrantLockReentrant, ReadWriteLock.WriteLock,
e.g;
Lock lock = new , ReentrantLockReentrant();
also you can provide your own implementation
public class MyLock implements Lock {
public void lock() {
}
public void lockInterruptibly() throws InterruptedException {
}
public boolean tryLock() {
return false;
}
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
public void unlock() {
}
public Condition newCondition() {
return null;
}
}
A lock is a thread synchronization mechanism like synchronized blocks except
locks can be more sophisticated than Java's synchronized blocks. Locks (and other more advanced synchronization mechanisms) are created using synchronized blocks, so it is not like we can get totally rid of the synchronized keyword.
From Java 5 the package java.util.concurrent.locks contains several lock implementations, so you may not have to implement your own locks. But you will still need to know how to use them, and it can still be useful to know the theory behind their implementation.
Consider this code:
public synchronized void onSignalsTimeout(List<SignalSpec> specs) {
if (specs != null && specs.size() > 0) {
for (SignalSpec spec : specs) {
ParsedCANSignal timeoutedSignal = new ParsedCANSignal();
SignalsProvider.getInstance().setSignal(spec.name, spec.parent.parent.channel, timeoutedSignal);
}
}
}
I've got simple question:
When Thread 1 calls onSignalsTimeout method, can Thread 2 access objects that are accessed in that method?
Can't find anywhere if 'synchronized' locks only access to this method or access to all objects used in this method.
First of all, forget about synchronized methods. A so-called synchronized method...
synchronized AnyType foobar(...) {
doSomething();
}
Is nothing but a shortcut way of writing this:
AnyType foobar(...) {
synchronized(this) {
doSomething();
}
}
There is nothing special about the method in either case. What is special is the synchronized block, and what a synchronized block does is very simple. When the JVM executes this:
synchronized(foo) {
doSomething();
}
It first evaluates the expression foo. The result must be an object reference. Then it locks the object, performs the body of the synchronized block, and then it unlocks the object.
But what does locked mean? It may mean less than you think. It does not prevent other threads from using the object. It doesn't prevent them from accessing the object's fields or, from updating its fields. The only thing that locking an object prevents is, it prevents other threads from locking the same object at the same time.
If thread A tries to enter synchronized(foo) {...} while thread B already has foo locked (either in the same synchronized block, or in a different one), then thread A will be forced to wait until thread B releases the lock.
You use synchronized blocks to protect data.
Suppose your program has some collection of objects that can be in different states. Suppose that some states make sense, but there are other states that don't make sense—invalid states.
Suppose that it is not possible for a thread to change the data from one valid state to another valid state without temporarily creating an invalid state.
If you put the code that changes the state in a synchronized(foo) block, and you put every block of code that can see the state into a synchronized block that locks the same object, foo, then you will prevent other threads from seeing the temporary invalid state.
Yes, other threads can access the objects used in the method; the synchronized keyword guarantees that no more than one thread at the time can execute the code of the method.
From https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html:
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. Note that constructors cannot be synchronized — using the
synchronized keyword with a constructor is a syntax error.
Synchronizing constructors doesn't make sense, because only the thread
that creates an object should have access to it while it is being
constructed.
In this context, synchronized simultaneously locks this method and any other method similarly marked as synchronized in your class.
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).
Suppose I create a thread safe object:
PriorityBlockingQueue<Object> safeQueue = new PriorityBlockingQueue<Object>();
If I synchronize on it:
synchronized (safeQueue) {
....
}
Does code that block:
// some non-synchronized block
Object value = safeQueue.poll();
No. The only time you get any blocking is if another thread is also doing a synchronized on the same object. If your code is synchronized (safeQueue) then a call to PriorityBlockingQueue.poll() would only block if poll() was a synchronized method or if the code used synchronized (this) code.
When you call safeQueue.poll() the PriorityBlockingQueue code is actually using an internal ReentrantLock, and not doing a synchronized (this). Here's the code for poll():
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return q.poll();
} finally {
lock.unlock();
}
}
Lastly, as you mention, PriorityBlockingQueue is already reentrant so you do not need to synchronize on it to allow multiple threads to access the queue. You could still need to synchronize on it if you needed to solve race conditions in your own code of course.
The short answer is: it depends on where the thread-safe class's thread safety comes from.
You have to depend on the class's documentation, or its implementation code if you want to go down that route (beware of changes in future versions...), or be defensive and not trust it, instead synchronizing on another object for your atomicity needs (or whatever else you're synchronizing for).
It certainly doesn't have to block, especially as many of the java.util.concurrent classes are non-blocking (and thus don't synchronize on themselves to achieve thread safety). On the other hand, if the class gets its thread safety from synchronized(this) (or, equivalently, synchronized instance methods), then yes, that'll block. An example of this is the map returned from Collections.synchronizedMap, in which that blocking is documented and is actually an intended feature (so that you can atomically query and modify the map).
It is possible if the object itself has methods that are synchronized on the instance. For example:
MyClass c = new MyClass();
synchronized(c) {
...
}
and MyClass is:
class MyClass {
// foo needs a lock on this
public synchronized void foo() {
...
}
}
Now, a call to c.foo(); outside of a synchronized section will still block if it's executed in parallel with the code written above.
For example, the old Java Vector class was synchronized internally like this, so locking on the object from the outside could interfere with the internal locking.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java Synchronization
I'm reading the book Beginning Android Games.
It uses synchronized() a lot but I don't really understand what it does. I haven't used Java in a long time and I'm not sure if I ever used multithreading.
In the Canvas examples it uses synchronized(this). However in the OpenGL ES example, it creates an Object called stateChanged and then uses synchronized(stateChanged). When the game state changes it calls stateChanged.wait() and then stateChanged.notifyAll();
Some code:
Object stateChanged = new Object();
//The onPause() looks like this:
public void onPause()
{
synchronized(stateChanged)
{
if(isFinishing())
state = GLGameState.Finished;
else
state = GLGameState.Paused;
while(true)
{
try
{
stateChanged.wait();
break;
} catch(InterruptedException e)
{
}
}
}
}
//The onDrawSurface looks like this:
public void onDrawFrame(GL10 gl)
{
GLGameState state = null;
synchronized(stateChanged)
{
state = this.state;
}
if(state == GLGameState.Running)
{
}
if(state == GLGameState.Paused)
{
synchronized(stateChanged)
{
this.state = GLGameState.Idle;
stateChanged.notifyAll();
}
}
if(state == GLGameState.Finished)
{
synchronized(stateChanged)
{
this.state = GLGameState.Idle;
stateChanged.notifyAll();
}
}
}
//the onResume() looks like this:
synchronized(stateChanged)
{
state = GLGameState.Running;
startTime = System.nanoTime();
}
The synchronized keyword is used to keep variables or methods thread-safe. If you wrap a variable in a synchronized block like so:
synchronized(myVar) {
// Logic involing myVar
}
Then any attempts to modify the value of myVar from another thread while the logic inside the synchronized block is running will wait until the block has finished execution. It ensures that the value going into the block will be the same through the lifecycle of that block.
This Java Tutorial can probably help you understand what using synchronized on an object does.
When object.wait() is called it will release the lock held on that object (which happens when you say synchronized(object)), and freeze the thread. The thread then waits until object.notify() or object.notifyAll() is called by a separate thread. Once one of these calls occurs, it will allow any threads that were stopped due to object.wait() to continue. This does not mean that the thread that called object.notify() or object.notifyAll() will freeze and pass control to a waiting thread, it just means these waiting threads are now able to continue, whereas before they were not.
When used like this:
private synchronized void someMehtod()
You get these effects:
1. 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.
2. 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.
(Taken from here)
You get a similar effect when you use a synchronized block of code:
private void someMethod() {
// some actions...
synchronized(this) {
// code here has synchronized access
}
// more actions...
}
As explained here
Java (which Android is based on) can run under multiple threads that can utilize multiple cpu cores. Multi-threading means that you can have Java doing two processes at the exact same moment. If you have a block of code or method that you need to ensure can only be operated by one thread at a time, you synchronize that block of code.
Here is the official Java explanation from Oracle
It's important to know that there is a processor/io costs involved with using synchronized and you only want to use it when you need it. It is also important to research what Java classes/methods are thread safe. For instance, the ++ increment operator is not guarateed to be thread safe, whereas you can easily create a block of synchronized code that increments a value using += 1.
only one thread can be active and inside block synchronized by given object.
calling wait stops gives up this right and deactivates current thread until someone call notify(all)()
Then the inactive thread start wanting to run in the synchronized block again, but is treated equaly with all other threads that wants it. Only one somehow chosen (programmer cannot influence nor depend on which one) actualy gets there.
Synchronized keyword in java is used for 2 things.
First meaning is so called critical section, i.e. part of code that can be accessed by one thread simultaneously. The object you pass to synchronized allows some kind of naming: if one code is run in synchronized(a) it cannot access other block that is into synchronized(a) but can access block of code into synchronized(b).
Other issue is inter-thread communication. Thread can wait until other thread notifies it. Both wait and notify must be written into synchronized block.
It was a very short description. I'd suggest you to search for some tutorial about multithreading and read it.
The keyword synchronized, together with the wait and notify operations form a nonblocking condition monitor, a construct useful for coordinating multiple threads.