Are these Java Threads in dealock? [duplicate] - java

This question already has answers here:
Java InputStream blocking read
(7 answers)
Closed 8 years ago.
I have written a sample program to illustrate the working with pipe is thread. I have created 2 threads.
Thread1 is sending "Hi this is thread1" and call wait() for thread 2 to complete.
Thread2 is printing the message sent by thread1 and also will also append into a string buffer, then once the entire message is received, thread2 will print the contents of string buffer and will call notify. Now after calling wait() and notify both threads tend to be in deadlock
Strangely, thread2 prints the message one but does not print the contents of string buffer.
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
synchronized (obj)
{
obj.wait();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
OUTPUT::
Hello I am thread1
Updated Resolution:
package com.tuto.MultiThreading;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeExample {
public static void main(String[] args) throws IOException, InterruptedException {
final Object obj=new Object();
final PipedOutputStream pipeoutstream=new PipedOutputStream ();
final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
Thread thread1= new Thread(new Runnable()
{
public void run() {
try {
pipeoutstream.write("Hello I am thread1".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
pipeoutstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (obj)
{
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
int data = pipeinputstream.read();
StringBuffer sb=new StringBuffer();
while(data != -1){
System.out.print((char) data);
sb.append((char)data);
data = pipeinputstream.read();
}
System.out.println();
System.out.println(sb.toString());
synchronized (obj) {
obj.notify();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
pipeinputstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(1);
}
}
Now i am a bit more confused. I just moved wait() from try catch to finally. How did it affect the blocking of Pipestream?

The problem is that
data = pipeinputstream.read();
in thread 2 is a blocking call. From the javadoc of PipedInputStream#read()
This method blocks until input data is available, the end of the
stream is detected, or an exception is thrown.
Thread 2 keeps waiting until one of those things happen. Since none of them will ever happen, the thread will not be able to notify the other.
This is not deadlock.
Note that even if that call unblocked and returned -1, thread 2 could still execute its notify before your thread 1 called wait. In which case, thread 1 would be a in a constant waiting state and your program would not terminate.

Related

Unexpected exception occurs during producer/consumer code in Java

I was looking at a producer-consumer example with wait and notify, even though it works some times it gives exception. Not able to figure out where the problem is.
Exception in thread "Thread-5" java.util.NoSuchElementException at
java.util.LinkedList.removeFirst(Unknown Source) at com.bhatsac.workshop.producerconsumer.ProdNConsumer.consumer(ProdNConsumer.java:55)
at com.bhatsac.workshop.producerconsumer.ProdConsumerInvoker.lambda$5 (ProdConsumerInvoker.java:35)
at java.lang.Thread.run(Unknown Source)
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;
public class ProdNConsumer {
LinkedList<Integer> list = new LinkedList<Integer>();
private int LIMIT = 1;
private volatile boolean shutdown = false;
private AtomicInteger counter=new AtomicInteger(0);
private Object lock=new Object();
public void produce() {
while (true) {
synchronized(lock){
System.out.println("In producer :)"+ list.size());
if(this.list.size()==this.LIMIT){
try {
System.out.println("In waiting state producer");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced by thread= "+ Thread.currentThread().getName());
list.add(counter.getAndIncrement());
System.out.println("Going to sleep for a while");
lock.notifyAll();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void consumer() {
while (true) {
synchronized(lock){
System.out.println("In consumer :)");
if(list.size()==0){
try {
System.out.println("In waiting state consumer");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("consumed by thread="+ Thread.currentThread().getName());
list.removeFirst();
lock.notifyAll();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ProdConsumerInvoker {
public static void main(String[] args) {
ProdNConsumer pc= new ProdNConsumer();
Thread tc1=new Thread(()->{pc.consumer();});
new Thread(()->{pc.produce();}).start();
new Thread(()->{pc.produce();}).start();
Thread tp1=new Thread(()->{pc.produce();});
new Thread(()->{pc.consumer();}).start();
new Thread(()->{pc.consumer();}).start();
tp1.start();
tc1.start();
}
}
Your producer and consumer threads are using the same lock. When a consumer wakes up and consumes an element, it calls lock.notifyAll(), which will wake up all consumers and producers waiting on it. Another consumer wakes up thinking there are items in the list, but it removes the first item from an empty list, causing the exception.
In the consumer, instead of if(list.size()==0), use while(list.size()==0). Similar reasoning applies to the producer as well. Just because the thread woke up doesn't mean that the condition it is waiting on is true. It only means that before the thread woke up the condition was true. It must check it again.

Producing and consuming into to list using threads?

I created two separate threads one for writing into a list and second for removing from the list.
package com.produ.consu;
public class Test {
public static void main(String[] args) {
Operations operations = new Operations();
Runnable r1 = new ThreadsClass(operations);
Runnable r2 = new ThreadsClass(operations);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.setName("READ");
t2.setName("WRITE");
t1.start();
t2.start();
}
}
Above is Test class where I created threads.
package com.produ.consu;
public class ThreadsClass implements Runnable {
Operations operations;
ThreadsClass(Operations operations){
this.operations=operations;
}
#Override
public void run() {
// TODO Auto-generated method stub
if(Thread.currentThread().getName().equals("WRITE")) {
operations.writeList();
}
else {
operations.readList();
}
}
}
Above is class calling synchronized methods based on the thread name:
import java.util.ArrayList;
import java.util.List;
public class Operations {
List<Integer> list=null;
int count=0;
boolean flag;
Operations(){
list=new ArrayList<>();
flag=true;
}
public synchronized void writeList() {
// TODO Auto-generated method stub
while(true) {
if(flag) {
count++;
list.add(count);
System.out.println("inise if block...."+Thread.currentThread().getName());
System.out.println(list);
flag=false;
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
notify();
}
}
}
public synchronized void readList() {
// TODO Auto-generated method stub
while(true) {
if(!flag) {
Integer i = list.remove(0);
System.out.println(i+"..removed at index by"+Thread.currentThread().getName());
flag=true;
notify();
}
else {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Above is where I mentioned functionality.
So write thread hast to write element to list and wait until it is removed by the second thread.
Once removed second should notify 1st and wait for until element inserted.
But getting...
inise if block....WRITE [1]
Not even removed and it has to be a continuous process.
Give me suggestions on given code.
You should wait() inside the else block also, otherwise the while will continue to run if the if is not satisfied and the other thread won't get a chance to execute.
After the read/write operation is performed the thread should call notify to wake up the other thread and itself should go in the waiting state.
public synchronized void writeList() {
while (true) {
if (flag) {
count++;
list.add(count);
System.out.println("inise if block...." + Thread.currentThread().getName());
System.out.println(list);
flag = false;
try {
notify(); //notify the read thread that write is complete
wait(); // go into the waiting state so that no further write is done until the current element is removed by the read thread.
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
wait(); //wait in else, otherwise while will run endlessly
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public synchronized void readList() {
while (true) {
System.out.println("in read");
if (!flag) {
Integer i = list.remove(0);
System.out.println(i + "..removed at index by" + Thread.currentThread().getName());
flag = true;
try {
notify(); //notify write thread that read is complete
wait(); //go into wait until new element is inserted
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
wait(); //wait in else otherwise while runs endlessly
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
You should replace the method synchronization with more granular synchronization: wrap the operations that access the list and update count with a synchronized block.
Alternatively, use a linked blocking queue to pass “messages” between threads (or, in more advanced scenarios, a messaging solution such as Akka, Kafka, zeromq, or other similar solutions)
Since you only add one elemet at a time you could also use a Exchanger.
Take a look at the Java concurrent package.
import java.io.IOException;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Foo {
public static void main(String[] args) throws IOException, InterruptedException {
final Exchanger<Integer> exchanger = new Exchanger<>();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
// producer
int count = 0;
while (!Thread.currentThread().isInterrupted()) {
try {
exchanger.exchange(count++);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
executorService.execute(() -> {
// reader
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("consume " + exchanger.exchange(null));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
System.in.read();
executorService.shutdownNow();
executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("Shut down");
}
}

Stop thread execution when it calls url.openStream() in a loop

Edit: I know what Thread.interrupt() does.
while (!Thread.currentThread().isInterrupted()) does not exit when I interrupt the thread.
I also tried to catch an exception from url.openStream(); when the
thread is interrupted (desperation, maybe it was a blocking method,
which is not) and exit the loop, without any success.
The application creates a Thread that continuously reads a URL. After 3 seconds that Thread gets interrupted but unfortunately continues to execute.
How to stop the thread from executing?
Code (Main.java, MyRunnable.java):
public class Main {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable("http://ninjaflex.com/");
Thread thread = new Thread(runnable);
thread.start();
sleep(3000);
thread.interrupt();
System.out.println("Thread.interrupt() invoked.");
}
private static void sleep(long timeMilli) {
try {
Thread.sleep(timeMilli);
} catch (Exception e) {
}
}
}
public class MyRunnable implements Runnable {
private String website;
MyRunnable(String website) {
this.website = website;
}
#Override
public void run() {
URL url = createUrl();
if (url != null) {
while (!Thread.currentThread().isInterrupted()) {
sleepOneSec();
readFromUrl(url);
System.out.println("Read from " + website);
}
System.out.println("Script: Interrupted, exiting.");
}
}
private URL createUrl() {
URL url = null;
try {
url = new URL(website);
} catch (MalformedURLException e) {
System.out.println("Wrong URL?");
}
return url;
}
private void sleepOneSec() {
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("Error sleeping");
}
}
private void readFromUrl(URL url) {
InputStream in = null;
try {
in = url.openStream();
} catch (Exception e) {
System.out.println("Exception while url.openStream().");
e.printStackTrace();
} finally {
closeInputStream(in);
}
}
private void closeInputStream(InputStream in) {
try {
in.close();
} catch (IOException e) {
System.out.println("Error while closing the input stream.");
}
}
}
Basically, your MyRunnable thread is interrupted during sleep. InterreuptedException is thrown but catched. By the way, it's a bad habit to catch Exception and you should not do that.
From the javadoc: "The interrupted status of the current thread is cleared when this exception is thrown".
Therefore, your while loop will never see the flag.
Replace the call to the sleepOneSec method with a simple Thread.sleep call. Catch InterruptedException outside your while loop. This will cause the loop to exit naturally:
try {
while (true) {
Thread.sleep(1000);
readFromUrl(url);
System.out.println("Read from " + website);
}
} catch (InterruptedException e) {
System.out.println("Script: Interrupted, exiting.");
}
I removed the MyRunnable.sleepOneSec and your code started to work.

Deadlock with CyclicBarrier?

I have an issue with the following piece of code for CyclicBarrier.
MyJavaCyclicBarrierExample.java:::::::
import java.util.Date;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class MyJavaCyclicBarrierExample {
public static void main(String[] args) {
//3 threads are part of the barrier, ServiceOne, ServiceTwo and this main thread calling them.
final CyclicBarrier barrier = new CyclicBarrier(2);
Thread serviceOneThread = new Thread(new ServiceOne(barrier));
Thread serviceTwoThread = new Thread(new ServiceTwo(barrier));
System.out.println("Starting both the services at "+new Date());
serviceOneThread.start();
serviceTwoThread.start();
//Lets say main also has to do some work
try {
System.out.println("Main is going to do some work....");
Thread.sleep(10000);
System.out.println("Main has finished its work....");
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
System.out.println("Main is now going to wait at the barrier....");
barrier.await();
System.out.println("Main woken up at the barrier....");
} catch (InterruptedException e) {
System.out.println("Main Thread interrupted!");
e.printStackTrace();
} catch (BrokenBarrierException e) {
System.out.println("Main Thread interrupted!");
e.printStackTrace();
}
System.out.println("Ending both the services at "+new Date());
}
}
ServiceOne.java :::::::::
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class ServiceOne implements Runnable {
private final CyclicBarrier cyclicBarrier;
public ServiceOne(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run() {
System.out.println("Starting service One...");
try {
Thread.sleep(3000); //assuming service one does some business logic here...
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("Service One has finished its work... waiting for others...");
try {
System.out.println("ServiceOne is now going to wait at the barrier....");
cyclicBarrier.await(); //Let's wait for the other threads at the cyclic barrier.
System.out.println("ServiceOne woken up at the barrier....");
} catch (InterruptedException e) {
System.out.println("Service one interrupted!");
e.printStackTrace();
} catch (BrokenBarrierException e) {
System.out.println("Service one interrupted!");
e.printStackTrace();
}
System.out.println("The wait is over, lets complete Service Two!");
}
}
ServiceTwo.java:::::::::
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class ServiceTwo implements Runnable {
private final CyclicBarrier cyclicBarrier;
public ServiceTwo(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run() {
System.out.println("Starting service Two....");
try {
Thread.sleep(2000); //assuming service one does some business logic here...
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("Service Two has finished its work.. waiting for others...");
try {
System.out.println("ServiceTwo is now going to wait at the barrier....");
cyclicBarrier.await(); //Let's wait for the other threads at the cyclic barrier.
System.out.println("ServiceTwo woken up at the barrier....");
} catch (InterruptedException e) {
System.out.println("Service one interrupted!");
e.printStackTrace();
} catch (BrokenBarrierException e) {
System.out.println("Service one interrupted!");
e.printStackTrace();
}
System.out.println("The wait is over, lets complete Service One!");
}
}
My question is, when I run this code with CyclicBarrier at two levels, it always ends up into a deadlock it seems. Whereas, when I run the code with CyclicBarrier at level 1 or three, i.e. new CyclicBarrier(1) or new CyclicBarrier(3), it always completes successfully. What is the issue with level two then?
CyclicBarrier is cyclic, which means it can be reused. When the barrier is initialized with argument 2, after tripped by serviceOneThread and serviceTwoThread, a new generation starts. The main thread can not trip it alone.
Maybe you need a CountDownLatch.

IllegalMonitorStateException while calling wait() in run()

I have created an java thread and passed an stack reference to it's constructor,
which initialize thread stack reference.
In run method i have created an synchronized block with that stack object,
the moment am calling wait in run inside synchronized block , i am getting IllegalMonitorStateException.
Thread Class :
public class Producer extends Thread {
Stack<String> stack=null;
public Producer(Stack<String> stack) {
this.stack=stack;
}
#Override
public void run() {
synchronized (stack) {
if(stack.isEmpty()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Main Class:
public class MainClass {
public static void main(String[] args) {
Stack<String> stack=new Stack<String>();
Producer p=new Producer(stack);
p.start();
}
}
Output :
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at demo.Producer.run(Producer.java:20)
For wait() (or notify()) to work, you must call it on the same object. What you have now is the same as
synchronized (stack) {
if(stack.isEmpty()){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
instead you should do
synchronized (stack) {
if(stack.isEmpty()){
try {
stack.wait(); // wait on the same object synchronized.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Note: as wait can wake spuriously you have do this in a loop or your method could return prematurely.
synchronized (stack) {
while (stack.isEmpty()){
try {
stack.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Categories

Resources