My code stops at "Producer started". Why wait() doesn't free lock? I use the same object in synchronized section, but it doesn't work.
class Processor {
public void produce() throws InterruptedException {
synchronized (this) {
System.out.println("Producer started");
wait();
System.out.println("Producer ended");
}
}
public void consume() throws InterruptedException {
System.out.println("Consumer started");
Scanner scanner = new Scanner(System.in);
synchronized (this) {
scanner.nextLine();
System.out.println("go to producer");
notify();
Thread.sleep(1000);
System.out.println("Consumer ended");
}
}
}
While I am running this code in different threads, I am using the same Processor object
public class Main {
public static void main(String[] args) throws InterruptedException {
Processor processor = new Processor();
Thread t1 = new Thread(() -> {
try {
processor.produce();
} catch (InterruptedException e) {}
});
Thread t2 = new Thread(() -> {
try {
processor.consume();
} catch (InterruptedException e) {}
});
t1.run();
t2.run();
t1.join();
t2.join();
}
}
Maybe try:
t1.start ();
t2.start ();
instead of
t1.run ();
t2.run ();
The problem here is that you call run() methods on Threads. You should use start() if you're about to run it in separate thread.
Related
I have 3 threads in my application, but I am allowed to run only 2 threads in parallel.
once 1 either of the tread will stop, 3rd thread will start.
I know Thread, runnable start(), run() etc in Java, But I dont know how to implement above situation. your little guidance will be very helpful
Try using semaphore;
public class Main {
private static final Semaphore SEMAPHORE = new Semaphore(2);
public static void main(String[] args) {
runThread(new Thread(() -> runInThread(1)));
runThread(new Thread(() -> runInThread(2)));
runThread(new Thread(() -> runInThread(3)));
}
public static void runThread(Thread thread) {
try {
SEMAPHORE.acquire();
thread.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void runInThread(int i) {
System.out.println("Thread " + i + " is running");
System.out.println("Thread " + i + " is waiting");
try {
Thread.sleep(i * 2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + i + " is finish");
SEMAPHORE.release();
}
}
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 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();
}
}
}
}
}
Please show me how to make thread wait. for example wait if i == 0 and go again when i == 1
public class Main {
public Main() {
}
public void method() {
Thread thread = new Thread(new Task());
// I want to make wait it when I want
// for example wait if i == 0 and go again when i = 1
}
public static void main(String[] args) {
new Main();
}
}
This is suitable for a CountDownLatch.
public static void main( String[] args ) throws Exception {
final CountDownLatch latch = new CountDownLatch( 1 );
System.out.println( "Starting main thread" );
new Thread( new Runnable() {
public void run() {
System.out.println( "Starting second thread" );
System.out.println( "Waiting in second thread" );
try {
latch.await();
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println( "Stopping second thread" );
}
} ).start();
Thread.sleep( 5000 );
System.out.println( "Countdown in main thread" );
latch.countDown();
Thread.sleep( 1000 );
System.out.println( "Stopping main thread" );
}
You might be able to do this with a semaphore
To avoid active waiting try use wait() and notify() or notifyAll() methods. Wait() can make thread stop until someone call notify() or notifyAll() on same object as wait(). One of condition is that thread must be in possession of monitor of object on which will be invoking wait(), notify() or notifyAll().
Here is an example
import java.util.concurrent.TimeUnit;
public class StartPauseDemo extends Thread {
volatile int i = 1;
public void pause() {
i = 0;
}
public synchronized void unPause() {
i = 1;
notify();// wake up thread
}
#Override
public void run() {
while (i==1) {
// logic of method for example printing time every 200 miliseconds
System.out.println(System.currentTimeMillis());
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i==0) {
synchronized (this) {// thread must possess monitor of object on
// which will be called wait() method,
// in our case current thread object
try {
wait();// wait until someone calls notify() or notifyAll
// on this thred object
// (in our case it is done in unPause() method)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
// test - pausing and unpausing every 1 sec
public static void main(String[] args) throws InterruptedException {
StartPauseDemo sp = new StartPauseDemo();
sp.start();// start thread
while (true) {
System.out.println("pausing");
sp.pause();
TimeUnit.SECONDS.sleep(1);
System.out.println("unpausing");
sp.unPause();
TimeUnit.SECONDS.sleep(1);
}
}
}
Output:
pausing
unpausing
1338726153307
1338726153507
1338726153709
1338726153909
1338726154109
pausing
unpausing
1338726155307
1338726155507
... and so on
Using such a flag is not necessarily the best approach, but to answer your specific question: you could make your int volatile. See below a simple example that you can run as is - the fact that i is volatile is crucial for this to work.
The output is (it could be different from run to run due to thread interleaving):
i=1
I'm doing something
I'm doing something
i=0
I'm waiting
I'm waiting
i=1
I'm doing something
I'm doing something
I'm doing something
i=0
I'm waiting
I'm waiting
interrupting
I was interrupted: bye bye
public class TestThread {
private static volatile int i = 0;
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
#Override
public void run() {
try {
while (true) {
while (i == 1) {
System.out.println("I'm doing something");
Thread.sleep(5);
}
while (i == 0) {
System.out.println("I'm waiting");
Thread.sleep(5);
}
}
} catch (InterruptedException ex) {
System.out.println("I was interrupted: bye bye");
return;
}
}
};
Thread t = new Thread(r);
t.start();
i = 1;
System.out.println("i=1");
Thread.sleep(10);
i = 0;
System.out.println("i=0");
Thread.sleep(10);
i = 1;
System.out.println("i=1");
Thread.sleep(10);
i = 0;
System.out.println("i=0");
Thread.sleep(10);
t.interrupt();
System.out.println("interrupting");
}
}