So I have been working on a simple wait/notify example in Java and for some reason I have not been able to get it to run properly. If anyone is able to see what might be the issue It would be very appreciated!
public class ThreadDemonstration
{
private String str = null;
Thread stringCreator = new Thread(new Runnable()
{
public void run()
{
synchronized(this)
{
str = "I have text";
notify();
}
}
});
private Thread stringUser = new Thread(new Runnable()
{
public void run()
{
synchronized(this)
{
if(str == null)
{
try {
System.out.println("str is null, I need help from stringCreator");
wait();
System.out.println(str);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
});
public static void main (String [] args)
{
ThreadDemonstration td = new ThreadDemonstration();
td.stringUser.start();
td.stringCreator.start();
}
}
My current output is:
str is null, I need help from stringCreator
So for some reason the thread stringCreator does not wake up the stringUser or am I missing something else entirely?
Thank you!
Your blocks are synchronized over different objects. They should be synchronized over a common object, for example the monitor object below:
public class ThreadDemonstration
{
private String str = null;
private final Object monitor = new Object();
Thread stringCreator = new Thread(new Runnable()
{
public void run()
{
synchronized(monitor)
{
str = "I have text";
monitor.notify();
}
}
});
private Thread stringUser = new Thread(new Runnable()
{
public void run()
{
synchronized(monitor)
{
while(str == null) //changed from if to while. This allows you to wait again if the thread gets woken up by something other than the appropriate notify.
{
try {
System.out.println("str is null, I need help from stringCreator");
monitor.wait();
//removed print statement from here
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println(str); //added print statement here. str is guaranteed to not be null here.
}
}
});
In order to avoid creating a separate object for synchronization, you can use synchronized(ThreadDemonstration.this) or synchronized(ThreadDemonstration.class) for example.
Try this :
private Thread stringUser = new Thread(new Runnable() {
//-----
System.out.println("str is null, I need help from stringCreator");
notify();
wait(100);
System.out.println(str);
//----
});
You need to use the wait and notify of the same instance in order for it to work. Since you create two different objects (2 instances of Runnable) it will not work. I've written a simple example using two different classes using the main class' instance for the intrinsic lock. You could also us a 'dummy object' (Object lock = new Object) for this.
public class ThreadDemonstration {
private static String text;
public ThreadDemonstration(){
Thread user = new Thread(new StringUser(this));
Thread creator = new Thread(new StringCreator(this));
user.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
creator.start();
}
public class StringCreator implements Runnable{
private Object lock;
StringCreator(Object lock){
this.lock = lock;
}
#Override
public void run() {
synchronized(lock){
text = "Yeeeehaaaaa";
lock.notify();
}
}
}
public class StringUser implements Runnable{
private Object lock;
StringUser(Object lock){
this.lock = lock;
}
#Override
public void run() {
synchronized(lock){
if((text == null)){
System.out.println("I need help!");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(text);
}
}
}
public static void main(String[] args){
new ThreadDemonstration();
}
}
Related
I have to create a program that simulate a bomb... The user has 5 seconds to digit the right code, if he can't, the bomb explodes.
class Codice implements Runnable{
String code;
#Override
public void run() {
code = JOptionPane.showInputDialog("Inserire codice disinnesco:");
if(code.equals(Bomba.check)) {
Bomba.s = "true";
JOptionPane.showMessageDialog(null, "Bomba disinnescata");
}
System.out.println(Bomba.s);
}
}
class Esplosione implements Runnable{
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!Bomba.s.equals("true")) {
JOptionPane.showMessageDialog(null, "BOOM!");
}
}
}
public class Bomba {
static String s = "false";
static String check = "123456";
public static void main(String[] args) throws IOException {
Codice c = new Codice();
Esplosione ex = new Esplosione();
Thread t1 = new Thread(c);
Thread t2 = new Thread(ex);
t1.start();
t2.start();
}
}
With this code i can insert the code, and if it's right the bomb doesn't explodes and the program finish. If 5 seconds passes, the message "boom" appears but the first thread doeasn't stop... How can i do?
There are many ways to coordinate between threads; interrupting is one way. Here is an example using Thread.interrupt. It dispenses with your state variable s, which becomes unnecessary:
import javax.swing.*;
import java.io.*;
class Codice implements Runnable {
String code;
Thread other;
Codice(Thread other) {
this.other = other;
}
#Override
public void run() {
code = JOptionPane.showInputDialog("Inserire codice disinnesco:");
if(code.equals(Bomba.check)) {
other.interrupt();
JOptionPane.showMessageDialog(null, "Bomba disinnescata");
}
}
}
class Esplosione implements Runnable {
#Override
public void run() {
try {
Thread.sleep(5000);
JOptionPane.showMessageDialog(null, "BOOM!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Bomba {
static String check = "123456";
public static void main(String[] args) throws IOException {
Esplosione ex = new Esplosione();
Thread t2 = new Thread(ex);
Codice c = new Codice(t2);
Thread t1 = new Thread(c);
t1.start();
t2.start();
}
}
I have the following code:
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}}
class ThreadB extends Thread{
#Override
public void run(){
synchronized(this){
notify();
}
}}
I'm pretty new to wait/notifyThreads and I need to find a way to wait before the notify() of Thread B until I call it explicitly from another class, preferably at first from a test case, later on from detached web service class. I don't get it, can you please help me out?
import java.lang.InterruptedException;
public class ThreadRunner {
public static void main(String[] args){
ThreadA a = new ThreadA();
ThreadB b = new ThreadB(a);
b.start();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
}
}
class ThreadA extends Thread {
String name = "threadA";
public void run() {
try {
synchronized (this) {
wait();
}
System.out.println(name + " " + "notified!");
} catch(InterruptedException e) {
// TODO: something
}
}
}
class ThreadB extends Thread {
ThreadA a;
String name = "threadB";
public ThreadB(ThreadA a) {
this.a = a;
}
#Override
public void run(){
a.start();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
synchronized (a) {
System.out.println(name + " " + "trying to notify A!");
a.notify();
}
}
}
If you want to wait for a task to be completed, I suggest using Java Concurrency API way:
public class WaitATaskExample {
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newSingleThreadExecutor();
Future<?> future = service.submit(() -> {
// your task here
Thread.sleep(5000);
return null;
});
try {
future.get(); // blocking call
} catch (InterruptedException | ExecutionException e) {
// handle exceptions
}
} finally {
if (service != null) {
service.shutdown();
}
}
}
}
Another approach using CountDownLatch:
public class WaitATaskExample {
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
Callable<Object> waitingTask = () -> {
latch.await(); // wait
return null;
};
Callable<Object> notifier = () -> {
Thread.sleep(2_000);
latch.countDown(); // notify
return null;
};
service.submit(waitingTask);
service.submit(notifier);
} finally {
if (service != null) {
service.shutdown();
}
}
}
}
I visited interview some recently. Interviewer asked me to write guaranteed deadlock.
I have wrote following:
public class DeadLockThreadSleep {
private static class MyThread implements Runnable {
private Object o1;
private Object o2;
#Override
public void run() {
try {
test(o1, o2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public MyThread(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
public void test(Object o1, Object o2) throws InterruptedException {
synchronized (o1) {
System.out.println("1.acquired: " + o1);
Thread.sleep(1000);
synchronized (o2) {
System.out.println("2.acquired: " + o2);
}
}
}
}
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
new Thread(new MyThread(o1, o2)).start();
new Thread(new MyThread(o2, o1)).start();
}
}
Then he asked if I sure that it is guaranted. I rememebered that Thread.sleep nothing guaranteed.
Then I wrote this code:
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
mainThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this answer was accepted.
Also he asked to write analog via wait/notify. I thought a lot and I cannot imagine how to write this.
Is it possible?
This may be done by creating a cycle where one thread holds a resource and waits for another resource whereas the other thread does the same but in reverse order.
Thread tholds resourceOne and waits for resourceTwo , whereas t1holds resourceTwo and waits for resourceOne
Below is a sample code:
public class WaitNotifyLock {
boolean isONHold = false;
public synchronized void hold(){
while(isONHold){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isONHold = true;
System.out.println(Thread.currentThread().getId() + " : Holded");
}
public synchronized void unHold(){
while(!isONHold){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getId() + " : Produced");
isONHold = false;
notify();
}
public static void main(String[] args) {
WaitNotifyLock resourceOne = new WaitNotifyLock();
WaitNotifyLock resourceTwo = new WaitNotifyLock();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
resourceOne.hold();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resourceTwo.hold();
resourceOne.unHold();
resourceTwo.unHold();
}
});
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
resourceTwo.hold();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resourceOne.hold();
resourceTwo.unHold();
resourceOne.unHold();
}
});
t.start();
t1.start();
}
}
A deadlock is a so-called liveness hazard (others are starvation, poor responsiveness, or livelocks), where two main types can be considered:
Lock-ordering deadlocks
Resource deadlocks
However, the Java documentation simplifies this as follows:
Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.
Hence, IMHO you could simply enforce a deadlock with this:
public class DeadlockDemo {
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
new Thread(() -> waitLeftNotifyRight(a, b)).start();
waitLeftNotifyRight(b, a);
}
public static void waitLeftNotifyRight(Object left, Object right) {
synchronized (left) {
try {
System.out.println("Wait");
left.wait();
} catch (InterruptedException e) { /* NOP */ }
}
synchronized (right) {
System.out.println("Notify");
right.notify();
}
}
}
This demo never terminates because the created thread waits on a's monitor, whereas the main thread waits on b's monitor. As a result, the corresponding notify() methods aren't invoked (which would terminate the program).
I try to understand java core synchronization.
I wrote code sample:
Program should write
left
right
10 times
package concurrency;
public class LeftRightWaitNotifyExample {
final static String str = "1";
public static void main(String[] args) {
new LeftLegThread(str).start();
new RightLegThread(str).start();
}
}
class LeftLegThread extends Thread {
String monitor;
public LeftLegThread(String str) {
monitor = str;
}
#Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
for (int i = 0; i < 10; i++) {
System.out.println("Left ");
wait();
}
}
}
}
class RightLegThread extends Thread {
String monitor;
public RightLegThread(String str) {
monitor = str;
}
#Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
while (true) {
System.out.println("Right ");
notify();
wait();
}
}
}
}
I get this output:
Left
Right
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at concurrency.LeftLegThread.makeStep(LeftRightWaitNotifyExample.java:35)
at concurrency.LeftLegThread.run(LeftRightWaitNotifyExample.java:23)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at concurrency.RightLegThread.makeStep(LeftRightWaitNotifyExample.java:61)
at concurrency.RightLegThread.run(LeftRightWaitNotifyExample.java:51)
Before I got this error when I used wait method non within synchronized block. But here I use wait within synchronized block
What is the cause of the problem and how to fix it?
update
I rewrite code according advice:
public class LeftRightWaitNotifyExample {
final static String str = "1";
public static void main(String[] args) throws InterruptedException {
new LeftLegThread(str).start();
Thread.sleep(100);
new RightLegThread(str).start();
}
}
class LeftLegThread extends Thread {
String monitor;
public LeftLegThread(String str) {
monitor = str;
}
#Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
for (int i = 0; i < 2; i++) {
System.out.println("Left ");
monitor.wait();
monitor.notify();
}
}
}
}
class RightLegThread extends Thread {
String monitor;
public RightLegThread(String str) {
monitor = str;
}
#Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
while (true) {
System.out.println("Right ");
monitor.notify();
monitor.wait();
}
}
}
}
current output:
Left
Right
Left
Right
Right
Why does Right outs 3 but Left only twice. Why?
You are synchronizing on monitor, so you should wait() on monitor, too:
monitor.wait();
Right now you are waiting on this, which is not the owner of the monitor because synchronization is on monitor.
Note that of course the notify should also be done on the monitor object, and that you might want to consider using notify/notifyAll in both threads. Otherwise it may happen that one thread starves waiting for a missing notification. Using a timeout (the overloaded version of wait) might also be a good idea to catch corner cases.
The reason - The current thread is not the owner of the object's monitor.To call wait() method the current thread must own this object's monitor.
In your case you are obtaining monitor on monitor object instead current object(this object).
you are trying to lock monitor object.But it is locking thread object (LeftLegThread,RightLegThread).Actually it is not locked with synchronization.
monitor.wait(); will fix.
public class LeftRightWaitNotifyExample {
final static String str = "1";
public static void main(String[] args) throws InterruptedException {
new LeftLegThread(str).start();
Thread.sleep(1000);
new RightLegThread(str).start();
}
}
class LeftLegThread extends Thread {
String monitor;
public LeftLegThread(String str) {
monitor = str;
}
#Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
while (true) {
System.out.println("Left ");
monitor.wait();
monitor.notify();
Thread.sleep(1000);
}
}
}
}
class RightLegThread extends Thread {
String monitor;
public RightLegThread(String str) {
monitor = str;
}
#Override
public void run() {
try {
makeStep();
} catch (InterruptedException e) {
}
}
private void makeStep() throws InterruptedException {
synchronized (monitor) {
while (true) {
System.out.println("Right ");
monitor.notify();
monitor.wait();
Thread.sleep(1000);
}
}
}
}
After execution the below code and throwing IllegalMonitorStateException
exception. I am getting error as:
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.blt.ThreadExample.main(ThreadExample.java:21)
I am new in multithreading, I want to use wait() and notify() in the code.
package com.blt;
public class ThreadExample implements Runnable {
public static void main(String args[])
{
System.out.println("A");
Thread T = new Thread(new ThreadExample());
Thread T1 = new Thread(new ThreadExample());
System.out.println("B");
try
{
T.setName("thread 1");
T.start();
T1.setName("thread 2");
System.out.println("C");
T.notify();
System.out.println("D");
T1.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
synchronized(ThreadExample.class)
{
for(int i=0; i<5; i++)
{
try
{
Thread.currentThread().wait(400);
System.out.println("Inside run=>"+Thread.currentThread().getName());
Thread.currentThread().sleep(2000);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}
As explained in the javadoc, you need to be within a synchronized block using the object as a monitor to be able to call notify or wait on that object.
Thread.currentThread() is going to be difficult to track, so I suggest you used another object. For example:
public class ThreadExample implements Runnable {
private static final Object lock = new Object();
public static void main(String args[]) {
System.out.println("A");
Thread T = new Thread(new ThreadExample());
Thread T1 = new Thread(new ThreadExample());
System.out.println("B");
try {
T.setName("thread 1");
T.start();
T1.setName("thread 2");
System.out.println("C");
synchronized(lock) {
lock.notify();
}
System.out.println("D");
T1.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
synchronized (lock) {
for (int i = 0; i < 5; i++) {
try {
lock.wait(400);
System.out.println("Inside run=>" + Thread.currentThread().getName());
Thread.currentThread().sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Note that there several other issues in your code, in particular:
you should always call wait in a loop (read the javadoc for more details)
sleep is a static method, no need to use Thread.currentThread().sleep(2000); - sleep(2000); will do the same.
These methods have to be enclosed in a synchronized block. Read about object locks in java tutorial.
In other words:
//thread 1
synchronized (commonObj) {
commonObj.wait();
}
//thread 2:
synchronized (commonObj) {
commonObj.notify();
}
Same question: How to use wait and notify in Java?
Try this.. and let me know if you have any doudt.
package com.blt;
public class ThreadExample implements Runnable {
public static void main(String args[]) {
Thread T1 = new Thread(new ThreadExample());
Thread T2 = new Thread(new ThreadExample());
try {
T1.setName("thread 1");
T1.start();
T2.setName("thread 2");
T2.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
synchronized (ThreadExample.class) {
for (int i = 0; i < 5; i++) {
try {
ThreadExample.class.notify();
System.out.println("Thread going to wait state::"+ Thread.currentThread().getName());
ThreadExample.class.wait(400);
System.out.println("Thread notified is::"+ Thread.currentThread().getName());
System.out.println("Thread going to sleep state::"+ Thread.currentThread().getName());
Thread.sleep(2000);
System.out.println("==========");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}