Is it true that notify works only after thread is finished? In code below I can't get notification until I comment while (true). How to tell main thread that part of thread job is done?
public class ThreadMain {
public Thread reader;
private class SerialReader implements Runnable {
public void run() {
while (true) {
try {
Thread.sleep(3000);
synchronized(this) {
System.out.println("notifying");
notify();
System.out.println("notifying done");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
}
ThreadMain() {
reader = new Thread(new SerialReader());
}
public static void main(String [] args) {
ThreadMain d= new ThreadMain();
d.reader.start();
synchronized(d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
}
}
You should try to avoid using wait and notify with the newer versions of Java, as they're difficult to get right. Try using something like a BlockingQueue instead
public class ThreadMain {
public final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
private class SerialReader implements Runnable {
public void run() {
while (true) {
try {
Thread.sleep(3000);
System.out.println("notifying");
queue.offer(Boolean.TRUE);
System.out.println("notifying done");
} catch (Exception e) {
System.out.println(e);
}
}
}
}
ThreadMain() {
reader = new Thread(new SerialReader());
}
public static void main(String [] args) {
ThreadMain d= new ThreadMain();
d.reader.start();
try {
d.queue.take(); // block until something is put in the queue
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
}
If you want to be notified when the Thread t completes, call t.join() in the calling Thread. This will block until t has finished its Runnable.
As user oddparity noted in the comments, you are calling wait() and notify() on different objects. A possible fix for this would be to make your SerialReader extend Thread rather than implement Runnable and then assigning reader to be a new instance of the SerialReader directly. :
public class ThreadMain {
public Thread reader;
private class SerialReader extends Thread {
public void run() {
while (true) {
try {
Thread.sleep(3000);
synchronized(this) {
System.out.println("notifying");
notify();
System.out.println("notifying done");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
}
ThreadMain() {
reader = new SerialReader();
}
public static void main(String [] args) {
ThreadMain d= new ThreadMain();
d.reader.start();
synchronized(d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
}
}
If you want to use Runnable with wait()/notify() you can do it this way :
public class ThreadMain {
public Thread reader;
private class SerialReader implements Runnable {
public void run() {
Thread thisThread = Thread.currentThread();
while (true) {
try {
Thread.sleep(3000);
synchronized (thisThread) {
System.out.println("notifying");
thisThread.notify();
System.out.println("notifying done");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
}
ThreadMain() {
reader = new Thread(new SerialReader());
}
public static void main(String[] args) {
ThreadMain d = new ThreadMain();
d.reader.start();
synchronized (d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
}
}
Related
I Wanted to print the 2 statements from the payFees class while the getReceipt class waits for the execution of the payFees class and vice versa with the getReceipt class and admissionCompleted class using Multithreading
It shows the java.lang.StackOverflowError.
But when I try to Initalise all the objects of these classes and call the start() and join(), It works perfectly.
Please Help.
package codes;
class payFees extends Thread
{
public payFees()
{
this.start();
getReceipt g= new getReceipt();
g.start();
}
public void run()
{
try
{
System.out.println("Withdraw Amount");
Thread.sleep(1000);
System.out.println("Fees Paid");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
class getReceipt extends Thread
{
payFees p=new payFees();
public void run()
{
try
{
p.join();
System.out.println("Ask for Receipt");
Thread.sleep(1000);
System.out.println("Receipt collected");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
class admissionCompleted extends Thread
{
public static void main(String args[])
{
new payFees();
getReceipt g=new getReceipt();
try
{
g.join();
System.out.println("Wait for confirmation");
Thread.sleep(1000);
System.out.println("Successfully completed admission process");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Task:
Sequentially override the state of the child stream and print to the console (possibly through an intermediate state): BLOCKED WAITING TERMINATED method Thread.sleep () not to use.
My code:
public class Test {
private static final Object M = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
synchronized(M) {
try {
M.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
synchronized(M) {
System.out.println(t.getState());
M.notify();
M.notifyAll();
}
System.out.println(t.getState());
System.out.println(t.getState());
t.join();
synchronized(M) {
M.notify();
M.notifyAll();
System.out.println(t.getState());
}
}
}
RESULT:
Question:
Pls help how to make it appear in the given sequence: BLOCKED WAITING TERMINATED
This is solution:
public class Test {
private static final Object M = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
try {
synchronized(M) {
M.notifyAll(); // notify before you stay on wait
M.wait();
M.notifyAll();
M.wait();
M.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
synchronized(M) { // you need to lock M before start thread
t.start();
M.wait(); //wait and notifyAll need for make sure before thread t already get lock M and will blocked next time
M.notifyAll();
System.out.println(t.getState()); //BLOCKED
M.wait();
System.out.println(t.getState()); //WAITING
M.notifyAll();
}
t.join();
synchronized(M) {
M.notifyAll();
System.out.println(t.getState());
}
}
}
I have a ConsumerProducer object on which I want to acquire lock from two different threads. The class is as below:
public class ConsumerProducer {
public String stringPool = null;
public void put(String s){
stringPool = s;
}
public String get(){
String ret = stringPool;
stringPool = null;
return ret;
}
}
The thread impl class is as below:
public class WaitNotifyTest implements Runnable {
private String threadType;
public ConsumerProducer cp;
public static volatile int i = 1;
public WaitNotifyTest(String threadType, ConsumerProducer cp) {
this.threadType = threadType;
this.cp = cp;
}
public static void main(String[] args) throws InterruptedException {
ConsumerProducer cp = new ConsumerProducer();
WaitNotifyTest test1 = new WaitNotifyTest("Consumer", cp);
WaitNotifyTest test2 = new WaitNotifyTest("Producer", cp);
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test2);
t1.start();
t2.start();
t1.join();
t2.join();
}
#Override
public void run() {
while (true) {
if (threadType.equalsIgnoreCase("Consumer")) {
synchronized (cp) {
try {
if (null != cp.get()) {
cp.wait();
}
consume();
System.out.println("notify from Consumer");
cp.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
synchronized (cp) {
try {
if (null == cp.get()) {
cp.wait();
}
produce();
System.out.println("notify from Producer");
cp.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (i == 5) {
break;
}
i++;
}
}
public void consume() {
System.out.println("Putting: Counter" + i);
cp.put("Counter" + i);
}
public void produce() {
System.out.println("getting: " + cp.get());
}
}
But when I run the code it is facing some kind of deadlock and it is stuck printing like
Putting: Counter3
notify from Consumer
Something is going terribly wrong but I am not able to identify. Please help.
Your consumer is doing producer's job and producer is doing consumer's job.
Exchange their responsibility and modify the condition to wait. Please refer to the code below.
Consumer will wait when there is nothing to get and he will release the lock of cp. So that producer has chance to go into the synchronized block.
Producer only produces when there is nothing or he will wait. After that, he will release the lock of cp. So that consumer has chance to go into the synchronized block.
Consumer is who get things away.
Producer is who put things to table.
According to your comment. You want to put Counter from 1 to 5, so you should add i++ only in Producer thread. How can you control its increase in both threads?
You don't judge whether it's consumer or producer calling the get() from cp object but assign null to stringPool. It's obvious wrong and will make consumer get null from public space. I add a new method clearString() which will set public space to null only when consumer has comsumed the product.
public class WaitNotifyTest implements Runnable {
private String threadType;
public ConsumerProducer cp;
public static volatile int i = 0;
public WaitNotifyTest(String threadType, ConsumerProducer cp) {
this.threadType = threadType;
this.cp = cp;
}
public static void main(String[] args) throws InterruptedException {
ConsumerProducer cp = new ConsumerProducer();
WaitNotifyTest test1 = new WaitNotifyTest("Consumer", cp);
WaitNotifyTest test2 = new WaitNotifyTest("Producer", cp);
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test2);
t1.start();
t2.start();
t1.join();
t2.join();
}
#Override
public void run() {
while (true) {
if (threadType.equalsIgnoreCase("Consumer")) {
synchronized (cp) {
try {
/*
* Consumer will wait when there is nothing to get and he will release the lock of cp.
* So that producer has change to go into the synchronized block.
*/
if (null == cp.get()) {
cp.wait();
}
consume();
System.out.println("notify from Consumer");
cp.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
synchronized (cp) {
try {
/*
* Producer only produce when there is nothing or he will wait. At the same time, he will release the lock of cp.
* So that consumer has chance to go into the synchronized block.
*/
if (null != cp.get()) {
cp.wait();
}
i++;
produce();
System.out.println("notify from Producer");
cp.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (i == 5) {
break;
}
}
}
public void consume() {
System.out.println("getting: " + cp.get());
cp.clearString();
}
public void produce() {
System.out.println("Putting: Counter" + i);
cp.put("Counter" + i);
}}
Also see the ConsumerProducer class.
public class ConsumerProducer {
public String stringPool = null;
public void put(String s){
stringPool = s;
}
public String get(){
return stringPool;
}
public void clearString(){
stringPool = null;
}
}
Updated code is here:
ConsumerProducer.java:
public class ConsumerProducer {
public volatile String stringPool = null;
public void put(String s){
this.stringPool = s;
}
public String get(){
String ret = this.stringPool;
//this.stringPool = null;
return ret;
}
//added
public void clearString(){
this.stringPool = null;
}
}
WaitNotifyTest.java
public class WaitNotifyTest implements Runnable {
private String threadType;
public ConsumerProducer cp;
public static volatile int i = 0;
public WaitNotifyTest(String threadType, ConsumerProducer cp) {
this.threadType = threadType;
this.cp = cp;
}
public static void main(String[] args) throws InterruptedException {
ConsumerProducer cp = new ConsumerProducer();
WaitNotifyTest test1 = new WaitNotifyTest("Consumer", cp);
WaitNotifyTest test2 = new WaitNotifyTest("Producer", cp);
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test2);
t1.start();
t2.start();
t1.join();
t2.join();
}
#Override
public void run() {
while (true) {
if (threadType.equalsIgnoreCase("Consumer")) {
synchronized (cp) {
try {
if (null == cp.get()) {
cp.wait();
}
consume();
System.out.println("notify from Consumer");
cp.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
synchronized (cp) {
try {
if (null != cp.get()) {
cp.wait();
}
i++;
produce();
System.out.println("notify from Producer");
cp.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (i == 5) {
break;
}
}
}
public void produce() {
System.out.println("Putting: Counter" + i);
cp.put("Counter" + i);
}
public void consume() {
System.out.println("getting: " + cp.get());
cp.clearString();
}
}
I'm trying to stop a java thread from a different class, but unable to figure out. I have looked into the below links, googled a lot from past 2 days but unable to nail down. May be a simple thing which i need to change but i'm out of options and hence posting it here.
Referred Links
java external threads (outside the class file it's used)
http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html
http://www.java2novice.com/java_thread_examples/
While typing the question, I referred the below links as well..
Stop a thread from outside
Below is my code sample. I'm able to start the WorkerThread from the MainThread and get into the loop. But unable to stop the thread started using the StopThread class.
I've also used the volatile option suggested in the below link.
http://tutorials.jenkov.com/java-concurrency/volatile.html
I feel I'm making a simple mistake, but not able to identify it.
//class WorkerThread
package main;
public class WorkerThread implements Runnable
{
public WorkerThread() {
isRunning = true;
}
public WorkerThread(boolean False) {
isRunning = False;
}
private volatile boolean isRunning;
public synchronized void stopThread() {
isRunning = false;
}
public synchronized boolean IsThreadRunning() {
return isRunning;
}
#Override
public void run()
{
int i = 1;
while(isRunning)
{
System.out.println("Loop " + i);
i++;
try { Thread.sleep(2000); }
catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
//class MainThread
package main;
public class MainThread
{
public static Thread t;
public static void main(String[] args)
{
t = new Thread(new WorkerThread());
t.start();
}
}
//class StopThread
package main;
public class StopThread
{
public static void main(String[] args)
{
//What should i write here to stop the thread started by MainThread
MainThread.t.interrupt();
}
}
public class MainThread
{
public static Thread t;
public static void main(String[] args)
{
t = new Thread(new WorkerThread());
t.start();
}
}
public class StopThread
{
public static void main(String[] args)
{
MainThread.t.interrupt();
}
}
It is not safe to call Thread.stop() it is listed as deprecated in JavaDocs
Also this may be just for the sake of this question, but why does your program have two main methods?
You have an opportunity to make use of what you defined volatile variable and gracefully come out of thread like below:
public class MainThread
{
public static WorkerThread workerThread;
public static void main(String[] args)
{
workerThread = new WorkerThread();
Thread t = new Thread(workerThread);
t.start();
}
}
public class StopThread
{
public static void main(String[] args)
{
Main.workerThread.stopThread();
}
}
Note: This solution works but not a perfect solution.
You can write and read value of isRunning variable from a properties file. This way you can have interaction between two different java processes. ThreadWorker just creates file upon initiation & and just makes attempt to read the file after that. StopThread modifies the properties file when triggered which should be picked up by ThreadWorker.
Check below example:
public class ThreadWorker implements Runnable
{
public volatile static boolean isRunning = false;
public ThreadWorker() {
Properties p = new Properties();
p.setProperty("isRunning", "1");
FileOutputStream out;
try {
//Writes all properties in appProperties file
out = new FileOutputStream("appProperties");
p.store(out, "---Thread Status----");
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run()
{
int i = 1;
String status = "1";
while("1".equals(status))
{
status = getStatus();
System.out.println("Loop " + i);
i++;
try { Thread.sleep(2000); }
catch (InterruptedException e) { e.printStackTrace(); }
}
}
public String getStatus() {
FileInputStream in;
Properties p = new Properties();
try {
in = new FileInputStream("appProperties");
p.load(in);
return p.getProperty("isRunning");
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//class StopThread
public class StopThread
{
public static void main(String[] args)
{
Properties p = new Properties();
p.setProperty("isRunning", "0");
FileOutputStream out;
try {
out = new FileOutputStream("appProperties");
p.store(out, "---Thread Status----");
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//class StopThread
public class StopThread
{
public static void main(String[] args)
{
Properties p = new Properties();
p.setProperty("isRunning", "0");
FileOutputStream out;
try {
out = new FileOutputStream("appProperties");
p.store(out, "---Thread Status----");
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Make thread t a public member of class MainThread, and then just call MainThread.t.interrupt() from StopThread
I followed the advice I found in this post using CountDownLatch and i'm running into a problem. I wrote up this test and ran it and my thread I created blocks when i try to synchronize on lock.
private CountDownLatch lock = new CountDownLatch(1);
#Test
public void testBlock() {
Runnable r = new Runnable() {
#Override
public void run() {
try
{
synchronized(this) {
this.wait(50);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
throw (new RuntimeException(e));
}
releaseLock();
}
};
Thread t = new Thread(r);
t.setDaemon(true);
t.start();
waitOnCallback();
}
private void releaseLock() {
synchronized(lock) { // Thread t blocks here
lock.countDown();
}
}
private void waitOnCallback() {
synchronized(lock) {
try
{
lock.await();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
Why isn't this working?
A CountDownLatch is not an object on which you need to synchronize (i.e. remove the synchronized(lock) blocks). all thread-safety is handled internally to the object itself.