synchronized object - java

I have simple code:
public class testing {
private static Object objToSync = new Object();
public static void main(String[] args) {
String obj1 = null;
synchronized(objToSync){
System.out.println("something one");
doSomething();
System.out.println("something three ");
}
doSomething();
}
private static void doSomething() {
synchronized(objToSync){
System.out.println("something two");
}
}
I have read several things but still getting confused with this one. Why does the doSomething in the main gets called? Is it not suppose to wait till the synchronized object gets unlocked? Sorry if I am sounding stupid, i am just confused.

Is it not suppose to wait till the synchronized object gets unlocked?
The lock is held by the thread, so the fact that you're synchronizing on it twice (in the case of the first call to doSomething in main) doesn't matter, it's on the same thread. If another thread then tried to enter a synchronized block on objToSync, that other thread would wait until this thread released all of its locks.
Your code will do this:
Enter main
Get a lock for the current thread on the objToSync object
Output "something one"
Call doSomething
Get a second lock for the current thread on objToSync
Output "something two"
Release the second lock for the current thread on objToSync
Return from doSomething
Output "something three"
Release the first lock for the current thread on objToSync
Call doSomething
Acquire a new lock (for that same thread) on objToSync
Output "something two"
Release that lock
Return from doSomething
Return from main
Here's an example using two threads:
public class SyncExample {
private static Object objToSync = new Object();
public static final void main(String[] args) {
Thread second;
System.out.println("Main thread acquiring lock");
synchronized (objToSync) {
System.out.println("Main thread has lock, spawning second thread");
second = new Thread(new MyRunnable());
second.start();
System.out.println("Main thread has started second thread, sleeping a moment");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Main thread releasing lock");
}
System.out.println("Main thread sleeping again");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Main thread waiting for second thread to complete");
try {
second.join();
}
catch (Exception e) {
}
System.out.println("Main thread exiting");
}
static class MyRunnable implements Runnable {
public void run() {
System.out.println("Second thread running, acquiring lock");
synchronized (objToSync) {
System.out.println("Second thread has lock, sleeping a moment");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Second thread releasing lock");
}
System.out.println("Second thread is done");
}
}
}
Output:
Main thread acquiring lock
Main thread has lock, spawning second thread
Main thread has started second thread, sleeping a moment
Second thread running, acquiring lock
Main thread releasing lock
Main thread sleeping again
Second thread has lock, sleeping a moment
Main thread waiting for second thread to complete
Second thread releasing lock
Second thread is done
Main thread exiting

Locks are reentrant so if some thread posses lock it can enter other synchronized blocks based on that lock. In your case you have only one thread (main) and he is doing something like this
synchronized(objToSync){
System.out.println("something one");
synchronized(objToSync){
System.out.println("something two");
}
System.out.println("something three");
}

Locks are reentrants for the same thread. That means a thread which has gained the lock of an object can access this and any other synchronized methods (or atomic statements, like here in your example) of the object. This thread will not need to gain the lock again, once it has gotten it.

Thats because your program has only 1 thread- the main thread.

Related

Threads logic in Java

I'm trying to resolve a university exercise. The class AImpl has a method ma(B b) that creates and runs two threads. These threads have to call mb1() and mb2() (they are simple methods that just print a text, so I didn't include them). The calling thread should then wait for mb1() to terminate before finishing.
My logic is:
The first thread enters and after finishing the execution of b.mb1() starts to wait() on the current object, releasing the mutex. Then the second thread runs and it does the same. When they are both waiting, the calling thread calls notifyAll() on the object, waking both of them. They execute b.mb2() and then terminate.
The problem is that when the first thread starts waiting with object.wait(), the control flow doesn't return on the calling thread and the program enters in a deadlock.
Where is my logic flawed?
public class AImpl{
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
BImpl b = new BImpl();
AImpl.ma(b);
}
public static void ma(B b) throws InterruptedException {
Thread thread = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
Thread thread1 = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
thread.run();
thread1.run();
synchronized(object){
object.notifyAll();
}
System.out.println("Program finished.");
}
}
The notify/notifyAll methods tell the scheduler to notify one/all of the threads currently waiting on the lock that notify or notifyAll was called on. But if a thread hasn't started waiting yet then it doesn't get notified.
The solution is to introduce a condition variable that keeps wait from being called if the notifying has happened already. Define it in the same scope as your lock:
public static volatile boolean ready = false;
Then use it to guard the wait block, like this:
while (!ready) {
object.wait();
}
The code calling notify/notifyAll needs to set the variable (it doesn't matter what order you do it in because the notification doesn't happen until the lock is released):
synchronized (object) {
ready = true;
object.notifyAll();
}
What happens:
If the waiting thread gets to the waiting part before the notifying thread does its notifying, then the waiting thread finds ready is false, so it enters the wait method, releases the lock, and stays there. Then the notifying thread changes the flag to true and wakes up the waiting thread, which can leave the wait, reacquire the lock, and then leave the loop now that the flag is set.
But if the notifying thread does its notify before the other thread waits, that's ok, because the ready flag now prevents the thread from entering the wait, it can skip over it.
Further reading: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

precise behaviour of interrupt() method with respective to thread states in java

I have read the post below
What does java.lang.Thread.interrupt() do? but i have not been able to get it completely right
I quote from #Mike_q answer to above question as below
Thread.interrupt() sets the interrupted status/flag of the target thread. Then code running in that target thread MAY poll the interrupted status and handle it appropriately. Some methods that block such as Object.wait() may consume the interrupted status immediately and throw an appropriate exception (usually InterruptedException)
It says while object is in WAITING it can consume interrupted status, so what happens when it is BLOCKED state waiting for object's lock ... ?
i have experimented below with that scenario and code is
at X: t2 is blocked
public class interruptsyc
{
static Object resource = new Object();
public static void main(String []args)
{
System.out.println("started main");
Thread1 t1=new Thread1("thread 1");
t1.start();
delay(1000);
Thread2 t2 =new Thread2("thread 2");
t2.start();
delay(1000);
t2.interrupt(); // X: at this point t2 is in blocked state waiting for resource's lock
System.out.println(t2.getName()+t2.interrupted());
delay(1000);
System.out.println("end main");
}
static void delay(long n)
{
try
{
Thread.sleep(n);
}
catch(InterruptedException ex)
{
System.out.println(Thread.currentThread().getName()+Thread.interrupted());
ex.printStackTrace();
}
}
static class Thread1 extends Thread{
Thread1(String name)
{
setName(name);
}
public void run()
{
synchronized(resource)
{
System.out.println("start 1");
delay(6000);
System.out.println("end 1");
}
}
}
static class Thread2 extends Thread{
Thread2(String name )
{
setName(name);
}
public void run()
{
synchronized(resource)
{
System.out.println("start 2");
delay(2000);
System.out.println("end 2");
}
}
}
}
and output has below
started main
start 1
false
end main
end 1
start 2
thread 2false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at interruptsyc.delay(interruptsyc.java:25)
at interruptsyc$Thread2.run(interruptsyc.java:59)
end 2
it seems that InterruptedException has been called ,when sleep method is called later... why is that ...?
again what is polling i didn't quite understand from what is said here
Polling occurs via the Thread.interrupted() method which returns the current thread's interrupted status AND clears that interrupt flag. Usually the thread might then do something such as throw InterruptedException.
again whenever i called Thread2.interrupted() method in above code it returned false (when i called just after t2.interrupt and in catch block)
it seems that InterruptedException has been called ,when sleep method is called later... why is that ...?
Because blocking/sleeping methods don't block immediately. They first check if the thread has been interrupted, and if it has been, they throw an InterruptedException immediately, in order for the thread to stop ASAP.
whenever i called Thread2.interrupted() method in above code it returned false
Because when blocking/sleeping methods throw an InterruptedException, they also clear the interrupt flag.
This is in the javadoc of Thread.sleep():
Throws InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

Java Thread never receiving notify

I've been trying to make a simple Java thread application, where one thread waits, and another wakes it up after 3 seconds. However, I can't seem to make it work and I just can't figure out why.
public class Deadlock extends Thread {
Object lock = new Object();
public static void main(String[] args) {
//WAITER THREAD
Deadlock waiter = new Deadlock() {
#Override
public void run() {
System.out.println("Waiter started");
synchronized(lock) {
try{
System.out.println("Waiter will wait for notify...");
lock.wait();
System.out.println("Woke up!");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}//run()
};
//WAKER THREAD
Deadlock waker = new Deadlock() {
#Override
public void run() {
System.out.println("Waker started");
synchronized(lock) {
System.out.println("Waker sleeping for 3 seconds.");
try{
Thread.sleep(3000);
}catch(InterruptedException e) {}
System.out.println("Waker notifying...");
lock.notifyAll();
}
}//run
};
waiter.start();
waker.start();
}
}
The output I get is:
Waiter started
Waiter will wait for notify...
Waker started
Waker sleeping for 3 seconds.
Waker notifying...
...and keeps running forever. I expected the waiter thread to wake up and the program to terminate.
Thanks
Your main problem is that the 'lock' is a class instance property so the two Deadlock instances do not share the same 'lock'. Hence, calling notifyAll() in the waker has no effect on the waiter because it's waiting on a different object. The simplest solution is to make 'lock' static:
static Object lock = new Object();
... I'd also make it private and final for good measure.
The second issue is that by starting the two threads together you don't really guarantee that the waiter will run first - I'd add a short delay before starting the waker.

Notification in thread

Will the thread give up the monitor immediately as soon as the notify() method is invoked like as it happens in wait(). Or when the notify() is invoked, will the monitor be released after the execution of the method is completed.
To which state will the thread move into when notify() is invoked. Waiting or Blocked state ?
The thread owning the monitor will continue to hold the monitor in case of notify().
notify()/notifyAll() just informs waiting thread that they can optain the lock again. Once a thread obtains the monitor it will exit the wait() method and continue.
To sum up: Thread involving notify()/notifyAll() will stay on RUNNING state as soon as the lock releases naturally (out of synchronized block/method).
The goal of notification is just to authorize waiting threads a future chance to get the lock as soon as this one is available.
A thread holds the monitor for an object as long as it is synchronized on that object. A notified thread will move to the BLOCKED state, and will obtain the monitor once the owning thread releases it by leaving the synchronized block/method that previously held the monitor.
For example, if thread A is blocking on a call to lock.wait() and thread B calls lock.notify(), thread A will leave the WAITING state and enter the BLOCKING state**, however thread A will not resume execution (i.e. enter the RUNNABLE state) until thread B leaves the synchronized block for lock.
** Assumes there are no other threads waiting on lock since the order that threads are notified is not guaranteed, which is why you should use notifyAll() as a rule (unless you know what you're doing and have a good reason not to).
Using code:
public class ThreadStateTest {
private static final Object lock = new Object();
public static void main(String[] args) {
synchronized (lock) {
new Thread(new RunnableTest()).start();
try {
Thread.sleep(1000);
System.out.println("this will print first");
lock.wait();
System.out.println("this will print third");
} catch (InterruptedException ex) {
}
}
}
private static class RunnableTest implements Runnable {
#Override
public void run() {
try {
synchronized (lock) {
lock.notifyAll();
Thread.sleep(1000);
System.out.println("this will print second");
}
Thread.sleep(1000);
System.out.println("this will print fourth");
} catch (InterruptedException ex) {
}
}
}
}

Reason for IllegalMonitorStateException

I am getting an Illegal State exception for following code :
synchronized (this) {
try {
Thread.currentThread().wait();
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
What i could made is synchronized on "this" will capture Monitor on Object calling the method and since i am calling wait on Current Thread object and i really don't have lock on that i am getting t error. Please validate my theory.
You call wait on the current thread, call it on this.
this.wait();
but then you will never get a notifyAll , because no thread that enters the synchronized block
can ever reach the notofyAll method. They all will wait for it first.
I guess you want one Thread to wait for another Thread to do some work.
Here is a short example of how synchronization between threads can work
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Object monitor = new Object();
Thread t1 = new Thread(new R1(monitor));
Thread t2 = new Thread(new R2(monitor));
t1.start();
t2.start();
t2.join();
t1.join();
}
public static class R1 implements Runnable {
private Object monitor;
public R1(Object monitor) {
this.monitor = monitor;
}
public void run() {
System.out.println("R1 entered run");
synchronized (monitor) {
try {
monitor.wait();
System.out.println("R1 got monitor back");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static class R2 implements Runnable {
private Object monitor;
public R2(Object monitor) {
this.monitor = monitor;
}
public void run() {
System.out.println("R2 entered run");
synchronized (monitor) {
System.out.println("R2 will sleep for 1 sec");
try {
Thread.sleep(1000);
System.out
.println("R2 will notify all threads waiting for monitor");
monitor.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Output is:
R1 entered run
R2 entered run
R2 will sleep for 1 sec
R2 will notify all threads waiting for monitor
R1 got monitor back
You have acquired the lock of
this(current object)
and you are calling `
wait()
` on current thread that is why.
you should acquire lock before calling wait, notify notifyAll
Case1
...
synchronized(this){
this.wait();
}
...
Case2
...
synchronized(this){
Thread.currentThread.wait();
}
...
Case 1 is sensible code. It waits until another thread calls notify[All]() on "this" object.
Case 2 looks silly. It could only execute if the current thread and "this" were the same object, or you already had a lock on the current thread. Otherwise, you'd get IllegalMonitorStateException. Synchronising on Thread objects is a Bad Thing, because you can't be sure what else might be synchronising on them.
By the way, if what you want to do is just pause for a while in the program, you should sleep(), not wait().
From the Java doc for Object class wait() method:
IllegalMonitorStateException - if the current thread is not the owner
of the object's monitor.
In your code, current thread is the owner of the monitor of this and wait is called on Thread.currentThread.
Replace Thread.currentThread().wait(); with this.wait();

Categories

Resources