Wait and Notify not behaving as expected , thread is getting hanged - java

Below is the code sample: Thread is getting hanged after consuming 5 or 6 values
I do not know where i am missing anything.And one more doubt that i Had was regarding calling the constructor of the MyIncrementor class. Initially I was trying to call the get and set in Producer and Consumer Class by creating new object of the MyIncrementor class, it was not working too
/**
*
*/
package multithreadingDemo;
/**
* #author Aquib
*
*/
public class ThreadCommDemo {
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
MyIncrementor mi=new MyIncrementor();
Producer1 p=new Producer1(mi);
Consumerrs c=new Consumerrs(mi);
Thread t1=new Thread(p);
Thread t2=new Thread(c);
t1.start();
t2.start();
}
}
class MyIncrementor {
int myCount;
boolean valueSet;
/**
* #return the myCount
*/
public synchronized int getMyCount() {
if (!valueSet) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("get" + myCount);
valueSet = true;
notifyAll();
return myCount;
}
/**
* #param myCount
* the myCount to set
*/
public synchronized void setMyCount(int myCount) {
if (valueSet) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Set" + myCount);
this.myCount = myCount;
valueSet = false;
notifyAll();
}
}
class Producer1 implements Runnable {
MyIncrementor mi;
public Producer1(MyIncrementor mi) {
// TODO Auto-generated constructor stub
this.mi=mi;
}
public void run() {
for (int i = 1; i < 10; i++) {
mi.setMyCount(i);
System.out.println("Produced" + mi.myCount);
try
{
Thread.currentThread().sleep((int)(Math.random() * 100));
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
}
}
}
class Consumerrs implements Runnable {
MyIncrementor mi;
public Consumerrs(MyIncrementor mi) {
// TODO Auto-generated constructor stub
this.mi=mi;
}
public void run() {
for (int i = 1; i < 10; i++) {
int val = mi.getMyCount();
System.out.println("Consumed" + val);
}
}
}

The first thing that stands out is the lack of a while.
if (valueSet) { // <-- if is wrong
try {
wait();
wait should be in a while. This ensures that the condition is met, rather than waking up for some other reason or no reason at all.
while (valueSet) {
try {
wait();
Presumably the problem is that you have your flag the wrong way around.
if (!valueSet) {
// ...
}
// ...
valueSet = true;
Presumably the if (should be a while) is intended that valueSet is true, but then you overwrite true with true rather than modifying the variable.
Also of not, Thread.sleep is a static method. It is incredibly misleading (though a common mistake) to call it on an instance.
Thread.currentThread().sleep(/* ... */); // misleading
should be
Thread.sleep(/* ... */);

You just have logical mistakes in your MyIncrementor class, you are setting valueSet incorrectly, so you have to either change your conditions or set the flag vice versa in getMyCount and setMyCount methods.
So, here is the corrected version of MyIncrementor:
class MyIncrementor {
int myCount;
boolean valueSet = false; //line changed - just to show that by default it is initialized to false
/**
* #return the myCount
*/
public synchronized int getMyCount() {
while (!valueSet) { //corrected as advised in comments, see #Tom Hawtin - tackline answer for details
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("get" + myCount);
valueSet = false; //line changed - after getting the value set flag to false
notifyAll();
return myCount;
}
/**
* #param myCount
* the myCount to set
*/
public synchronized void setMyCount(int myCount) {
while (valueSet) { //corrected as advised in comments, see #Tom Hawtin - tackline answer for details
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Set" + myCount);
this.myCount = myCount;
valueSet = true; //line changed - after setting the value set flag to true
notifyAll();
}
}

Related

java wait and notify

I'm taking one Integer variable and sharing with two threads. One thread should print even numbers and one thread should print odd number sequentially.
But notify() throwing IllegalMonitorStateException.
package mywaitnotifytest;
public class App {
public static void main(String[] args) {
Integer i=0;
Even even = new Even(i);
even.setName("EvenThread");
Odd odd = new Odd(i);
odd.setName("OddThread");
even.start();
odd.start();
}
}
class Even extends Thread{
Integer var;
Even(Integer var){
this.var=var;
}
#Override
public void run() {
while(true){
synchronized (var) {
if(var%2==0){
try {
var.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
var++;
System.out.println(Thread.currentThread().getName()+" "+var);
var.notify();
}
}
}
}
class Odd extends Thread{
Integer var;
Odd(Integer var){
this.var=var;
}
#Override
public void run() {
while(true){
synchronized (var) {
if(var%2!=0){
try {
var.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
var++;
System.out.println(Thread.currentThread().getName()+" "+var);
var.notify();
}
}
}
}
And the output is :
OddThread 1
Exception in thread "OddThread" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at mywaitnotifytest.Odd.run(App.java:67)
I think this is sufficiently different to the usual answer to give another one.
In this case you are using synchronized. When you apply a lock it is on a object not a reference.
synchronized (var) {
This locks the object var references, not on var as a field.
var++;
This replaces the object var points to. It is the same as
var = Integer.valueOf(var.intValue() + 1);
Note: Integer and indeed all the primitive wrappers are Immutable. When you perform any operation on them you are actually unboxing, calculating using the primitive value and re-boxing the object. It is possible to get the same object back if it is pooled. e.g.
Integer i = 10;
i += 0; // gives back the same object.
However, if the object is not pooled
Double d = 10;
d += 0; // creates a new object.
var.notify();
Attempts the call notify on the new object, not the one which was locked.
You shouldn't attempt to lock a field which you mutate. It won't do what it appears to do. You also shouldn't lock on a pooled object. In this case you could have another thread using the same Integer for an unrelated purpose and notify() will wake up an unrelated thread.
To use wait/notify correctly, you should
notify() or notifyAll() after a state change in another shared field.
you should use a while loop for wait() to check the state change.
If you don't do this
notify can be lost if another thread is not waiting.
wait can wake spuriously, even when no notify was called.
For the above requirement what is the edit suggested in the code? How do i share the same object for multiple threads?
public class PingPong implements Runnable {
static class Shared { int num; }
private final Shared var;
private final int bit;
public static void main(String[] args) {
Shared var = new Shared();
new Thread(new PingPong(var, 0), "EvenThread").start();
new Thread(new PingPong(var, 1), "OddThread").start();
}
PingPong(Shared var, int bit) {
this.var = var;
this.bit = bit;
}
#Override
public void run() {
try {
String name = Thread.currentThread().getName();
while (true) {
synchronized (var) {
while (var.num % 2 == bit)
var.wait();
var.num++;
System.out.println(name + " " + var.num);
var.notify();
}
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
}
Instead of using Integer wrapper class,I created my own class and now It works fine.
package mywaitnotifytest;
public class App {
public static void main(String[] args) {
MyInt i = new MyInt(0);
Even even = new Even(i);
even.setName("EvenThread");
Odd odd = new Odd(i);
odd.setName("OddThread");
even.start();
odd.start();
}
}
class Even extends Thread {
MyInt var;
Even(MyInt var) {
this.var = var;
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
synchronized (var) {
if (var.i % 2 == 0) {
try {
var.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
var.i++;
System.out.println(Thread.currentThread().getName() + " " + var.i);
var.notify();
}
}
}
}
class Odd extends Thread {
MyInt var;
Odd(MyInt var) {
this.var = var;
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
synchronized (var) {
if (var.i % 2 != 0) {
try {
var.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
var.i++;
System.out.println(Thread.currentThread().getName() + " " + var.i);
var.notify();
}
}
}
}
class MyInt {
int i = 0;
public MyInt(int i) {
super();
this.i = i;
}
#Override
public String toString() {
// TODO Auto-generated method stub
return "" + i;
}
}

Getting illegal monitor state exception on notify

The below program is supposed to print even and odd numbers by two different threads but I am getting illegal monitor exception on notify method in the below code :
public class oddeven {
static volatile Integer t = 0;
public static void main(String as[]) {
oddrunnable or = new oddrunnable(t);
evenrunnable er = new evenrunnable(t);
Thread t1 = new Thread(or, "odd");
Thread t2 = new Thread(er, "even");
t1.start();
t2.start();
}
}
class oddrunnable implements Runnable {
Integer t;
public oddrunnable(Integer t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t % 2 == 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t++;
t.notify();
}
}
}
}
class evenrunnable implements Runnable {
Integer t;
public evenrunnable(Integer t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t % 2 != 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t++;
t.notify(); // <-------------------exception on this line
}
}
}
}
the notify method is called on the synchronized object itself. Not sure why this is coming :
Current thread id even
Exception in thread "even" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at evenrunnable.run(oddeven.java:86)
at java.lang.Thread.run(Thread.java:619)
Integers in java wrapper are immutable, so as soon as you do t++, you are going to assign a new Integer object which you didn't took lock against and hence you get IllegalMonitorStateException.
Instead of Integer, use AtomicInteger and then use incrementAndGet api to increment the value of counter.
The problem is in using Integer object for synchronization and than doing increment(++) operation on it. I think its creating new integer object and than all the synchronized logic is going for toss. I am not sure about it as while debugging your code, eclipse was not showing whether it created new object.
A better alternative is to use some wrapper object around your integer or AtomicInteger class. Here is your code with AtomicInteger class used
public class oddeven {
static volatile AtomicInteger t = new AtomicInteger(0);
public static void main(String as[]) {
oddrunnable or = new oddrunnable(t);
evenrunnable er = new evenrunnable(t);
Thread t1 = new Thread(or, "odd");
Thread t2 = new Thread(er, "even");
t1.start();
t2.start();
}
}
class oddrunnable implements Runnable {
AtomicInteger t;
public oddrunnable(AtomicInteger t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t.intValue() % 2 == 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t.incrementAndGet();
t.notify();
}
}
}
}
class evenrunnable implements Runnable {
AtomicInteger t;
public evenrunnable(AtomicInteger t) {
this.t = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
synchronized (t) {
while (true) {
if (t.intValue() % 2 != 0) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Current thread id " + Thread.currentThread().getName());
t.incrementAndGet();
t.notify(); // <-------------------exception on this line
}
}
}
}

Why hasn't the PriorityBlockingQueue queue to sort elements according to the priority

This my code ,the code run the end is not my excepted.
I think the PriorityBlockingQueue sorted by Priority but the end is not my expected,Who can told me why.
public class TestPriorityQueue {
static Random r=new Random(47);
public static void main(String args[]) throws InterruptedException{
final PriorityBlockingQueue q=new PriorityBlockingQueue();
ExecutorService se=Executors.newCachedThreadPool();
//execute producer
se.execute(new Runnable(){
public void run() {
int i=0;
while(true){
q.put(new PriorityEntity(r.nextInt(10),i++));
try {
TimeUnit.MILLISECONDS.sleep(r.nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
//execute consumer
se.execute(new Runnable(){
public void run() {
while(true){
try {
System.out.println("take== "+q.take()+" left:== ["+q.toString()+"]");
try {
TimeUnit.MILLISECONDS.sleep(r.nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("shutdown");
}
}
class PriorityEntity implements Comparable<PriorityEntity> {
private static int count=0;
private int id=count++;
private int priority;
private int index=0;
public PriorityEntity(int priority,int index) {
this.priority = priority;
this.index=index;
}
public String toString(){
return id+"* [index="+index+" priority="+priority+"]";
}
//数字大,优先级高
public int compareTo(PriorityEntity o) {
return this.priority < o.priority ? 1
: this.priority > o.priority ? -1 : 0;
}
}
The following are the results,I would be very grateful to you for your help
Some observations:
in most cases the size of your queue was 1. Clearly, no sort order is relevant in any of those.
In a few cases the queue size may have been two, and in no such case does the output insinuate that an element of lower priority was preferred. I stress the verb "insinuate" because...
your code has no synchronized blocks so nothing prevents the following sequence of operations:
q.take(); // consumer thread
q.put(); // producer thread
q.toString(); // consumer thread
with the legitimate outcome of q.toString() showing an element of higher priority than was taken.

JProgressBar Doesn't Start Until Try-catch finishes

I am writing a program which uses Random.ORG api. When I click calculate button, JProgressBar starts right after the opeartion is being done and stay freezed until this moment.
I tried extra try-catch clauses, if statements and bool-gates. None of them worked, how could I fix it?
kazananiBelirleButon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
try {
HashMap<String, Object> randoms = randSonuc.generateSignedIntegers(5, 0, 10);
System.out.println(randoms.toString());
String test = randoms.toString().substring(randoms.toString().indexOf("{r")+1, randoms.toString().indexOf(", da")).replace("random=", "{\"random\":") + "}";
System.out.println(tarihiYazdir(test,14));
cekilisTarihiTextPane.setText(tarihiYazdir(test,2).toString());
sonucPane.setText("\n"+sonuclariYazdir(test,0));
} catch (RandomOrgSendTimeoutException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgKeyNotRunningError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientRequestsError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientBitsError e1) {
System.out.print("lol");
e1.printStackTrace();
} catch (RandomOrgBadHTTPResponseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgRANDOMORGError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgJSONRPCError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
Swing is single threaded. Calling listeners, painting/updating UI all happen on a single thread called the Event Dispatch Thread (EDT).
Since you do all your work in the event handler code, the Swing UI cannot be updated until you return from your method (actionPerformed()).
Read this tutorial: Concurrency in Swing
What you should do is do your time-consuming work in a separate thread and only do short tasks in the EDT (e.g. UI updates).
Also check out the SwingWorker class which is designed to perform lengthy GUI-interaction tasks in a background thread.
Try using swing worker in your method.
Swing Worker
Here is an example from old version of swing worker. Firs you need to add SwingWorker class to your project:
import javax.swing.SwingUtilities;
/**
* This is the 3rd version of SwingWorker (also known as
* SwingWorker 3), an abstract class that you subclass to
* perform GUI-related work in a dedicated thread. For
* instructions on using this class, see:
*
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
*
* Note that the API changed slightly in the 3rd version:
* You must now invoke start() on the SwingWorker after
* creating it.
*/
public abstract class SwingWorker
{
private Object value; // see getValue(), setValue()
private Thread thread;
/**
* Class to maintain reference to current worker thread
* under separate synchronization control.
*/
private static class ThreadVar
{
private Thread thread;
ThreadVar(Thread t)
{
thread = t;
}
synchronized Thread get()
{
return thread;
}
synchronized void clear()
{
thread = null;
}
}
private ThreadVar threadVar;
/**
* Get the value produced by the worker thread, or null if it
* hasn't been constructed yet.
*/
protected synchronized Object getValue()
{
return value;
}
/**
* Set the value produced by worker thread
*/
private synchronized void setValue(Object x)
{
value = x;
}
/**
* Compute the value to be returned by the <code>get</code> method.
*/
public abstract Object construct();
/**
* Called on the event dispatching thread (not on the worker thread)
* after the <code>construct</code> method has returned.
*/
public void finished()
{
}
/**
* A new method that interrupts the worker thread. Call this method
* to force the worker to stop what it's doing.
*/
public void interrupt()
{
Thread t = threadVar.get();
if (t != null)
{
t.interrupt();
}
threadVar.clear();
}
/**
* Return the value created by the <code>construct</code> method.
* Returns null if either the constructing thread or the current
* thread was interrupted before a value was produced.
*
* #return the value created by the <code>construct</code> method
*/
public Object get()
{
while (true)
{
Thread t = threadVar.get();
if (t == null)
{
return getValue();
}
try
{
t.join();
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt(); // propagate
return null;
}
}
}
/**
* Start a thread that will call the <code>construct</code> method
* and then exit.
*/
public SwingWorker()
{
final Runnable doFinished = new Runnable()
{
public void run()
{
finished();
}
};
Runnable doConstruct = new Runnable()
{
public void run()
{
try
{
setValue(construct());
}
finally
{
threadVar.clear();
}
SwingUtilities.invokeLater(doFinished);
}
};
Thread t = new Thread(doConstruct);
threadVar = new ThreadVar(t);
}
/**
* Start the worker thread.
*/
public void start()
{
Thread t = threadVar.get();
if (t != null)
{
t.start();
}
}
}
Then add your logic inside:
SwingWorker worker = new SwingWorker() {
#Override
public Object construct() {
// add your code here
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
// and so on...
return 0;
}
};
worker.start();
So the end resuld should look like this (Note that this is untested code):
kazananiBelirleButon.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SwingWorker worker = new SwingWorker() {
#Override
public Object construct() {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
try {
HashMap<String, Object> randoms = randSonuc.generateSignedIntegers(5, 0, 10);
System.out.println(randoms.toString());
String test = randoms.toString().substring(randoms.toString().indexOf("{r")+1, randoms.toString().indexOf(", da")).replace("random=", "{\"random\":") + "}";
System.out.println(tarihiYazdir(test,14));
cekilisTarihiTextPane.setText(tarihiYazdir(test,2).toString());
sonucPane.setText("\n"+sonuclariYazdir(test,0));
} catch (RandomOrgSendTimeoutException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgKeyNotRunningError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientRequestsError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgInsufficientBitsError e1) {
System.out.print("lol");
e1.printStackTrace();
} catch (RandomOrgBadHTTPResponseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgRANDOMORGError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (RandomOrgJSONRPCError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return 0;
}
};
worker.start();
});

DeadLock in producer Consumer

I have following classes :
package com.akshu.multithreading;
public class ThreadResource {
static int a;
static boolean Value =false;
public synchronized int getA() {
while(Value == false){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Value= false;
notify();
return a;
}
public synchronized void setA(int a) {
while(Value == true)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ThreadResource.a = a;
Value=true;
notify();
}
}
------------------
/**
*
*/
package com.akshu.multithreading;
/**
* #author akshu
*
*/
public class MyThreadA implements Runnable {
int a = 0;
ThreadResource tR= new ThreadResource();
#Override
public void run() {
for (int i = 0; i < 15; i++) {
tR.setA(++a);
System.out.println(" value of a :"+a);
}
}
}
------------
package com.akshu.multithreading;
public class MyThreadB implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
ThreadResource tR =new ThreadResource();
for (int i = 0; i < 15; i++) {
System.out.println("getA()"+tR.getA());
}
}
}
----
package com.akshu.multithreading;
public class ThreadExecutionPoint {
public static void main(String args[]) {
Thread th1 = new Thread(new MyThreadA());
Thread th2 = new Thread(new MyThreadB());
th1.start();
th2.start();
}
}
I am trying to understand producer consumer problem via above code .When i execute the above code i am getting
value of a :1
getA()1
Program gets stuck here only (do not gets terminate).
Someone Please explain what wrong i am doing here?
Declare Value as volatile
I.e. static volatile boolean Value =false;
You have declared your set/get methods synchronized. This means that they are lock on this (the object's intrinsic lock).
But in your code you instantiate a different ThreadResource for each thread thereby not making them synchronized since this is different for each case.
Change your code as follows:
public class MyThreadA implements Runnable {
ThreadResource tR;
public MyThreadA(ThreadResource tr) {
this.tR = tr;
}
// your run method here NOT declaring a ThreadResource anymore!!!
}
and same for MyThreadB
Then in ThreadExecutionPoint
ThreadResource tr = new ThreadResource();
Thread th1 = new Thread(new MyThreadA(tr));
Thread th2 = new Thread(new MyThreadB(tr));

Categories

Resources