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();
}
}
}
}
Related
This question already has an answer here:
Why Java throw java.lang.IllegalMonitorStateException when I invoke wait() in static way synchronized block?
(1 answer)
Closed 2 years ago.
In the below code for producer and consumer, I thought that the produce() and consume() methods are synchronized on Class Lock (Processor.class), but i am getting an exception stating IllegalMonitorStateException, which occurs for objects on which we don't acquire lock but we notify on that objects.
Can anyone tell me where i have gone wrong in the program.
package ProducerConsumer;
public class Main {
public static void main(String[] args) {
Processor processor = new Processor();
Thread producer = new Thread(new Runnable() {
public void run() {
try {
processor.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumer = new Thread(new Runnable() {
public void run() {
try {
processor.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("\t\t\tStarting both producer and consumer Threads.");
producer.start();
consumer.start();
try {
producer.join();
consumer.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t\t\tEnding all the Threads.");
}
}
import java.util.List;
import java.util.ArrayList;
public class Processor {
private List<Integer> list = new ArrayList<>();
private int value = 0;
private final int LIMIT = 5;
public void produce() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.size() == LIMIT){
System.out.println("Waiting for consumer to consume resources");
wait();
}
else{
value++;
System.out.println("The produced resource is : "+value);
list.add(value);
notify();
}
}
}
}
public void consume() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.isEmpty()){
System.out.println("Waiting for producer to produce the resources");
wait();
}
else{
System.out.println("The consumer Consumed Resource is : "+list.remove(0));
notify();
}
}
}
}
}
Your wait() & notify() are invoked on this i.e. Processor processor = new Processor(); but your are locking/synchronizing on Processor.class object. You can fix your code to work as below.
class Processor {
private List<Integer> list = new ArrayList<>();
private int value = 0;
private final int LIMIT = 5;
public void produce() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.size() == LIMIT){
System.out.println("Waiting for consumer to consume resources");
Processor.class.wait();
}
else{
value++;
System.out.println("The produced resource is : "+value);
list.add(value);
Processor.class.notify();
}
}
}
}
public void consume() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.isEmpty()){
System.out.println("Waiting for producer to produce the resources");
Processor.class.wait();
}
else{
System.out.println("The consumer Consumed Resource is : "+list.remove(0));
Processor.class.notifyAll();
}
}
}
}
}
I am trying to create a program that will carry on running automatically without me having to do anything. I am a bit confused on how to implement runnable in java so I can create a thread that will go to sleep for a certain period of time and then run the re-run the program after the sleep period is over.
public class work {
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.information();
}
private ConfigurationBuilder OAuthBuilder() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("dy1Vcv3iGYTqFif6m4oYpGBhq");
cb.setOAuthConsumerSecret("wKKJ1XOPZbxX0hywDycDcZf40qxfHvkDXYdINWYXGUH04qU0ha");
cb.setOAuthAccessToken("4850486261-49Eqv5mogjooJr8lm86hB20QRUpxeHq5iIzBLks");
cb.setOAuthAccessTokenSecret("QLeIKTTxJOwpSX4zEasREtGcXcqr0mY8wk5hRZKYrH5pd");
return cb;
}
public void information() throws IOException, InterruptedException {
ConfigurationBuilder cb = OAuthBuilder();
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
try {
User user = twitter.showUser("ec12327");
Query query = new Query("gym fanatic");
query.setCount(100);
query.lang("en");
String rawJSON =null ;
String statusfile = null;
int i=0;
try {
QueryResult result = twitter.search(query);
for(int z = 0;z<5;z++){
for( Status status : result.getTweets()){
System.out.println("#" + status.getUser().getScreenName() + ":" + status.getText());
rawJSON = TwitterObjectFactory.getRawJSON(status);
statusfile = "results" + z +".txt";
storeJSON(rawJSON, statusfile);
i++;
}
}
System.out.println(i);
}
catch(TwitterException e) {
System.out.println("Get timeline: " + e + " Status code: " + e.getStatusCode());
if(e.getErrorCode() == 88){
Thread.sleep(900);
information();
}
}
} catch (TwitterException e) {
if (e.getErrorCode() == 88) {
System.err.println("Rate Limit exceeded!!!!!!");
Thread.sleep(90);
information();
try {
long time = e.getRateLimitStatus().getSecondsUntilReset();
if (time > 0)
Thread.sleep(900000);
information();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
private static void storeJSON(String rawJSON, String fileName) throws IOException {
FileWriter fileWriter = null;
try
{
fileWriter = new FileWriter(fileName, true);
fileWriter.write(rawJSON);
fileWriter.write("\n");
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
} finally {
if(fileWriter!=null) {
fileWriter.close();
}
}
}
}
You have severable options to implement a thread in Java.
Implementing Runnable
When a class implements the Runnable interface, he has to override the run() method. This runnable can be passed to the constructor of a Thread. This thread can then be executed using the start() method. If you'd like to have this thread run forever and sleep, you could do something like the following:
public class HelloRunnable implements Runnable {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Extending Thread
Thread itself also has a run() method. When extending thread, you can override the Thread's run() method and provide your own implementation. Then you'd have to instantiate your own custom thread, and start it in the same way. Again, like the previous you could do this:
public class HelloThread extends Thread {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}
Source: Oracle documentation
Building on the previous answer, you need to either extend Thread or implement Runnable on your Work class. Extending Thread is probably easier.
public class work extends Thread {
public void run() {
// your app will run forever, consider a break mechanism
while(true) {
// sleep for a while, otherwise you'll max your CPU
Thread.sleep( 1000 );
this.information();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.start();
}
// ... rest of your class
}
public static void main(String[] args){
Thread thread = new Thread(runnable); // create new thread instance
thread.start(); // start thread
}
public static Runnable runnable = new Runnable(){
#Override
public void run(){
final int DELAY = 500;
while(true){
try{
// Code goes here;
Thread.sleep(DELAY)
} catch(Exception e){
e.printStackTrace();
}
}
}
}
I'm learning concurrency and made some naive program to play with ExecutorService and Future tasks.
Also I want to check why instanceof is bad in some cases.
public class Test {
static enum Some {
FOO;
}
static abstract class Foo {
public abstract Some getType();
}
static class FooExt extends Foo {
public Some getType() {
return Some.FOO;
}
}
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(2);
final CountDownLatch start = new CountDownLatch(1);
Future<Integer> f1 = service.submit(new Callable<Integer>() {
#Override
public Integer call() {
try {
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task started...");
int a = 0;
Foo foo = new FooExt();
while (!Thread.currentThread().isInterrupted()) {
if (foo instanceof FooExt) {
a++;
}
}
System.out.println("Task ended...");
return a;
}
});
Future<Integer> f2 = service.submit(new Callable<Integer>() {
#Override
public Integer call() {
try {
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task started...");
int a = 0;
Foo foo = new FooExt();
while (!Thread.currentThread().isInterrupted()) {
if (foo.getType() == Some.FOO) {
a++;
}
}
System.out.println("Task ended...");
return a;
}
});
start.countDown();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
service.shutdownNow();
System.out.println("service is shutdowned...");
try {
System.out.println("instanceof: "+f1.get());
System.out.println("enum: "+f2.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
but unfortunately my code is never terminated, and I cant get any values from my tasks :(
Hi I have executed your program. I got the following output:
Task started...
Task started...
Task ended...
service is shutdowned...
Task ended...
instanceof: 1287184
enum: 1247375
This code terminates.
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();
}
}
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();
}
}
}
}
}