I am trying to implement standard Producer Consumer problem using java.
I done some code to do it.
Here is the code:
Producer Class:
class Producer implements Runnable
{
public Producer()
{
new Thread(this,"Producer").start();
}
public synchronized void put()
{
while(Q.valueset)
{
try
{
wait();
}
catch(Exception e)
{
System.out.println(e);
}
}
Q.valueset=true;
Q.i++;
System.out.println("Put:"+Q.i);
notify();
}
public void run()
{
while(true)
{
put();
}
}
}
Consumer class:
class Consumer implements Runnable
{
public Consumer()
{
new Thread(this,"Consumer").start();
}
public synchronized void get()
{
while(!Q.valueset)
{
try
{
wait();
}
catch(Exception e)
{
System.out.println(e);
}
}
Q.valueset=false;
notify();
System.out.println("Get:"+Q.i);
}
public void run()
{
while(true)
{
get();
}
}
}
Another class for Static variables:
class Q
{
static boolean valueset=false;
static int i;
}
I am having one more class which only contains main and creates the instance of Producer And Consumer.
Now when i am trying to run this program it gives following output:
Put:1
put:2
Got:1
Got:2
I am having misconception related to Wait() and notify() that how it works and how object enters and out's from the monitor.i wanted to clear that concept.
Here the problem is also arising due to Wait and notify().
I know this is very basic question related to Multithreading but these these will help me to clear my misconception.
And i also wanted to understand what is the problem in my code.
I already gone through the following link:
producer - consumer multithreading in Java
You need to wait() and notify() on some shared object. What you are doing now by using synchronized is waiting on the respective objects themselves, i.e. the Producer is waiting on the Producer and the Consumer on the Consumer object. You need to wait on something in Q.
From the Javadoc:
notify(): Wakes up a single thread that is waiting on this object's monitor.
wait(): The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
This object's monitor in your case is this, which is your Producer in the put() case and the Consumer in the get() case. But in order for the notify to notify the other Thread, they need to have the same monitor, i.e. they need to wait() on the same object. This object can be e.g. a Object variable in your Q.
To get you started, this is what I mean:
class Q
{
static boolean valueset=false;
static int i;
static Object myLock = new Object();
}
public void put() {
synchronized (Q.myLock) {
while (Q.valueset) {
try {
Q.myLock.wait();
} catch (Exception e) {
System.out.println(e);
}
}
Q.i++; //you forgot this as well
System.out.println("Put:" + Q.i);
Q.valueset = true;
Q.myLock.notify();
}
}
You can fill in the Consumer class yourself...
Put:1
Get:1
Put:2
Get:2
Put:3
Get:3
Put:4
Get:4
This post explains the relationship between notify, wait, and other things you are looking for.
Difference between wait() and sleep()
Related
I state that I read about thread, but I've never used.
So I ask to you :)
I have two thread: A and B,
where A manages the GUI, and B manages the logic.
I would start with A.
Then when A draw the GUI, I would pause it, to wait B that reach a point X into run method.
And when B reach the X point into run method, I pause B, and resume A.
A and B share some variable to manage the GUI, and the logic...
Can I do it? if yes, how? :)
Using wait() and notify() methods:
wait() - Causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object.
notify() - Wakes up a single thread that is waiting on this object's monitor.
You can block threads using the wait and notify methods of the Object class, but it can be tricky to get right. Here's an example inside an infinite loop in a Runnable:
public class Example implements Runnable {
private volatile boolean running = true;
private volatile boolean paused = false;
private final Object pauseLock = new Object();
#Override
public void run() {
while (running) {
synchronized (pauseLock) {
if (!running) { // may have changed while waiting to
// synchronize on pauseLock
break;
}
if (paused) {
try {
pauseLock.wait(); // will cause this Thread to block until
// another thread calls pauseLock.notifyAll()
// Note that calling wait() will
// relinquish the synchronized lock that this
// thread holds on pauseLock so another thread
// can acquire the lock to call notifyAll()
// (link with explanation below this code)
} catch (InterruptedException ex) {
break;
}
if (!running) { // running might have changed since we paused
break;
}
}
}
// Your code here
}
}
public void stop() {
running = false;
// you might also want to interrupt() the Thread that is
// running this Runnable, too, or perhaps call:
resume();
// to unblock
}
public void pause() {
// you may want to throw an IllegalStateException if !running
paused = true;
}
public void resume() {
synchronized (pauseLock) {
paused = false;
pauseLock.notifyAll(); // Unblocks thread
}
}
};
(For more information on why we need to synchronize as illustrated above whilst calling wait and notifyAll, see the Java tutorial on the subject.)
If another Thread calls this Runnable's pause() method, then the Thread running the runnable will block when it gets to the top of the while loop.
Note that it is not possible to pause a thread at any arbitrary point. You need the Thread to periodically check whether it should pause and block itself if so.
I would expect that you don't need to pause the GUI thread. The operating system will take care of that, and it needs to be ready to respond in case the user does something.
One other thought is to make sure the shared variables are properly synchronized between the two threads. I tried answering a question relating to that recently, see here.
you can use a CountDownLatch. When Thread A has to wait for Thread B will call countDownLatchInstance.await(); When B reach the X point will invoke countDownLatchInstance.countDown(); allowing A to continue its execution flow.
When you say
A manages the GUI
I hope you do not refer to the UI/Main Thread
,
public class Mutex {
private final AtomicBoolean lock;
private final Object mutex;
public Mutex(boolean lock) {
this.lock = new AtomicBoolean(lock);
this.mutex = new Object();
}
public void step() {
if (lock.get()) synchronized(mutex) {
try {
mutex.wait();
} catch (InterruptedException ex) {}
}
}
public void lock() {
lock.set(true);
}
public void unlock() {
lock.set(false);
synchronized(mutex) {
mutex.notify();
}
}
}
Just add Mutex object to your thread and make getter.
public class MyThread extends Thread {
private final Mutex mutex;
public MyThread() {
this.mutex = new Mutex(false);
}
public Mutex getMutex() {
return this.mutex;
}
#Override
public void run() {
while (!isInterrupted()) {
mutex.step();
// do your code
}
}
}
If you want to pause the thread just call
myThread.getMutex().lock();
If you want to resume the thread just call
myThread.getMutex().unlock();
That's the way I got thread's wait and notify working for me:
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
MyThread t = new MyThread();
t.lock = lock;
t.run();
while (true) {
try {
synchronized (lock) {
lock.wait();
}
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MyThread extends Thread {
Object lock;
#Override
public void run() {
JFrame fr = new JFrame("Anothing");
JButton btn = new JButton("Next");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
synchronized (lock) {
lock.notify();
}
}
});
fr.setLayout(new FlowLayout());
fr.add(btn);
fr.setSize(400, 400);
fr.setVisible(true);
}
}
Then, whenever I press the button, the other thread wakes up, executes one round and waits for a new clicking.
The java primitive to suspend and resume a thread is deprecated. See this to figure how you can achieve best what you need - http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Check how you can do the equivalent of suspend & resume
What should I use instead of Thread.suspend and Thread.resume?
As with Thread.stop, the prudent approach is to have the "target thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify.
Example code is given in the same answer to help you achieve this.
I've an object that's created when the class is instantiated. I create a lock i-e; wait() on that object inside a background thread, however the app still gets unresponsive. My understanding of synchronization/locking is that if object.wait() is called in the main thread than it's equivalent to blocking the main thread however if it's called inside a background thread (even though the object upon which wait() is called in the main thread, shouldn't cause problems).
Can someone please help me out understanding this?
Example code:
class MyClass {
private final Object myLockObject = new Object();
public void connect() {
new Thread(new Runnable{
mSocket.connect();
myLockObject.wait(); // causing ANR
}).start();
}
private void socketConnectCallback() {
//upon callback
myLockObject.notifyAll();
}
}
class MyAndroidService extends Service {
public void onStartCommand() {
MyClass myClassObject = new MyClass();
myClassObject.connect();
//it immediately returns here even with the code written above.
}
}
First of all, this code will throw an IllegalMonitorStateException. This is because before calling object.wait(), you need to make sure that you are holding the object's monitor. One way to do this is to use:
synchronised(object) {
// this thread now owns the object's monitor
object.wait();
}
Further, the thread that calls for object.wait() relinquishes its ownership on that object's monitor and waits for some other thread to notify it. Once it gets the notification, it will wait until it reacquires the object's monitor (since some other thread might be having the ownership of that monitor even if the waiting thread got the notify signal). Then it continues normal execution.
In your case, the background thread should block, and the main thread should continue executing normally. Isn't this what you have mentioned is happening?
I don't know if this will help so much, but I can't comment so I want to get your attention to this code:
newThread(new Runnable {
mSocket.connect();
myLockObject.wait();
}).start();
This must be like:
(new Thread( new Runnable() {
public void run() {
try {
mSocket.connect(); // connect takes argument(s)
} catch (IOException e) {
// Catch the excpetion
}
try {
myLockObject.wait();
} catch (InterruptedException e) {
// Catch the excpetion
}
}
})).start();
and since Runnable is a functional interface you can use lambda expression instead of creating a new object.
Edit:
I think I figured out what do you want to do, if you want to make a thread that connects the socket and then wait to be notified and want it to acquire the intrinsic lock of the object myLockObject to prevent interleaving then you have to put the code you want to be executed by the thread in a guarded block:
private final void connectSocket() {
synchronized(myLockObject) {
try {
mSocket.connect(null);
} catch (IOException e) {
}
try {
myLockObject.wait();
} catch (InterruptedException e) {
}
}
}
and in the connect method just call connectSocket
public void connect() {
new Thread(new Runnable() {
public void run() {
connectSocket();
}
}).start();
}
I am trying to understand how deadlocks are created. I've understood that by using two threads on two synchronized methods, a deadlock can be created.
Went through many examples from the net.
Can a deadlock be created with wait and notify?
Every time a thread is on wait, it will be notified. So how does this end up in a deadlock?
Illustration of an example will be helpful.
Deadlock is caused when two threads try to obtain the same, multiple locks in different order:
// T1
synchronized (A) {
synchronized (B) {
// ...
}
}
// T2
synchronized (B) {
synchronized (A) {
// ...
}
}
The only way to prevent deadlocks is to make sure that all threads obtain locks in the same order--either they all do A then B, or they all do B then A.
If you don't have multiple locks, then you don't have a deadlock. However, you can get thread starvation or other things that may look similar to deadlock.
Say thread 1 enters a synchronized block on method A and then waits. Thread 2 then attempts to enter the synchronized block on method A. Thread 1 is waiting for a notify, and thread 2 is waiting on the synchronized block. Everything is now waiting. Some other thread will have to notify the object on which thread 1 is waiting. This is just one scenario that can create a deadlock. There are all kinds of ways to do it.
A thread which is on wait will not be notified unless some code explicitly notifies it. Therefore the example you are looking for is absolutely trivial:
public static void main(String[] args) {
synchronized(String.class) {
String.class.wait();
}
}
and this hangs forever. Technically, though, it is not a deadlock, which requires two or more threads involved in a closed cycle where each thread waits for the next one to unblock it.
Something close to wait/notify deadlock:
public class Example
{
volatile boolean isNotified = false;
public synchronized void method1() {
try
{
isNotified = false;
while (!isNotified)
wait();
notifyAll();
System.out.println("Method 1");
} catch (InterruptedException e) {/*NOP*/}
}
public synchronized void method2() {
try {
isNotified = true;
while (isNotified)
wait();
notifyAll();
System.out.println("Method 2");
} catch (InterruptedException e) {/*NOP*/}
}
public static void main(String[] args)
{
Example example = new Example();
Thread thread1 = new Thread()
{
public void run()
{
example.method1();
}
};
Thread thread2 = new Thread()
{
public void run()
{
example.method2();
}
};
thread1.start();
thread2.start();
}
}
I have three classes, one that is meant to represent a pile of urls
private Queue<String> queue = new LinkedList<String>();
public Queue<String> getQueue() {
return queue;
}
private int limit = 5;
private int stillParsing;
public synchronized String getNextString() throws InterruptedException {
while (queue.isEmpty()||stillParsing > limit) {
System.out.println("no for you "+ queue.peek());
wait();
}
System.out.println("grabbed");
notify();
stillParsing++;
System.out.println(queue.peek());
return queue.remove();
}
public synchronized void doneParsing() {
stillParsing--;
}
}
A thread class whose run method is
public void run(){
try {
sleep(30);
for(;;){
String currenturl = pile.getNextString();
//(do things)
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
pile.doneParsing();
}
}
And a mapper that actually adds objects into the pile of urls using this snipet
while (urls.hasMoreTokens()) {
try{
word.set(urls.nextToken());
String currenturl = word.toString();
System.out.println(currenturl);
pile.getQueue().add(currenturl);
From debugging what I think happens is that all of the threads try to get from the queue at once before the mapper has a chance to populate it and they get stuck waiting. Unfortunately all of the threads waiting is causing my program to hang up and not add more urls to the queue. How should I go about taking care of this issue? Preferably while still using wait notify.
while (urls.hasMoreTokens()) {
try {
word.set(urls.nextToken());
String currenturl = word.toString();
System.out.println(currenturl);
pile.getQueue().add(currenturl);
In the above code, you're breaking the encapsulation of the pile by adding something to its queue without going though a method of the pile. You should not have a getQueue() method in this class: all the accesses to this shared data structure should be synchronized on the same lock. You should thus add a synchronized method allowing to add a URL to the queue. And this method should also call notify() (or better: notifyAll()), in order to wake up the threads that are waiting for some element to be in the queue:
public synchronized void addUrl(String url) {
queue.add(url);
notifyAll();
}
Even without reading all lines of your code and explanations I can say that your usage of wait and notify are buggy.
Method wait() is blocking. It exits only when notify() on the same monitor is called. This means that you cannot put both wait() and notify() from the same thread. You simply never arrive to notify() because wait() is blocked forever.
Other version of wait(): wait(timeout) is blocked but is limited by specified timeout.
Moreover wait/notify pair work only if they are written into synchronized block:
// thread-1
synchronoized(obj) {
obj.wait();
}
// thread-2
synchronoized(obj) {
obj.notify();
}
Thread-1 will exit wait when thread-2 calls notify.
I state that I read about thread, but I've never used.
So I ask to you :)
I have two thread: A and B,
where A manages the GUI, and B manages the logic.
I would start with A.
Then when A draw the GUI, I would pause it, to wait B that reach a point X into run method.
And when B reach the X point into run method, I pause B, and resume A.
A and B share some variable to manage the GUI, and the logic...
Can I do it? if yes, how? :)
Using wait() and notify() methods:
wait() - Causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object.
notify() - Wakes up a single thread that is waiting on this object's monitor.
You can block threads using the wait and notify methods of the Object class, but it can be tricky to get right. Here's an example inside an infinite loop in a Runnable:
public class Example implements Runnable {
private volatile boolean running = true;
private volatile boolean paused = false;
private final Object pauseLock = new Object();
#Override
public void run() {
while (running) {
synchronized (pauseLock) {
if (!running) { // may have changed while waiting to
// synchronize on pauseLock
break;
}
if (paused) {
try {
pauseLock.wait(); // will cause this Thread to block until
// another thread calls pauseLock.notifyAll()
// Note that calling wait() will
// relinquish the synchronized lock that this
// thread holds on pauseLock so another thread
// can acquire the lock to call notifyAll()
// (link with explanation below this code)
} catch (InterruptedException ex) {
break;
}
if (!running) { // running might have changed since we paused
break;
}
}
}
// Your code here
}
}
public void stop() {
running = false;
// you might also want to interrupt() the Thread that is
// running this Runnable, too, or perhaps call:
resume();
// to unblock
}
public void pause() {
// you may want to throw an IllegalStateException if !running
paused = true;
}
public void resume() {
synchronized (pauseLock) {
paused = false;
pauseLock.notifyAll(); // Unblocks thread
}
}
};
(For more information on why we need to synchronize as illustrated above whilst calling wait and notifyAll, see the Java tutorial on the subject.)
If another Thread calls this Runnable's pause() method, then the Thread running the runnable will block when it gets to the top of the while loop.
Note that it is not possible to pause a thread at any arbitrary point. You need the Thread to periodically check whether it should pause and block itself if so.
I would expect that you don't need to pause the GUI thread. The operating system will take care of that, and it needs to be ready to respond in case the user does something.
One other thought is to make sure the shared variables are properly synchronized between the two threads. I tried answering a question relating to that recently, see here.
you can use a CountDownLatch. When Thread A has to wait for Thread B will call countDownLatchInstance.await(); When B reach the X point will invoke countDownLatchInstance.countDown(); allowing A to continue its execution flow.
When you say
A manages the GUI
I hope you do not refer to the UI/Main Thread
,
public class Mutex {
private final AtomicBoolean lock;
private final Object mutex;
public Mutex(boolean lock) {
this.lock = new AtomicBoolean(lock);
this.mutex = new Object();
}
public void step() {
if (lock.get()) synchronized(mutex) {
try {
mutex.wait();
} catch (InterruptedException ex) {}
}
}
public void lock() {
lock.set(true);
}
public void unlock() {
lock.set(false);
synchronized(mutex) {
mutex.notify();
}
}
}
Just add Mutex object to your thread and make getter.
public class MyThread extends Thread {
private final Mutex mutex;
public MyThread() {
this.mutex = new Mutex(false);
}
public Mutex getMutex() {
return this.mutex;
}
#Override
public void run() {
while (!isInterrupted()) {
mutex.step();
// do your code
}
}
}
If you want to pause the thread just call
myThread.getMutex().lock();
If you want to resume the thread just call
myThread.getMutex().unlock();
That's the way I got thread's wait and notify working for me:
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
MyThread t = new MyThread();
t.lock = lock;
t.run();
while (true) {
try {
synchronized (lock) {
lock.wait();
}
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MyThread extends Thread {
Object lock;
#Override
public void run() {
JFrame fr = new JFrame("Anothing");
JButton btn = new JButton("Next");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
synchronized (lock) {
lock.notify();
}
}
});
fr.setLayout(new FlowLayout());
fr.add(btn);
fr.setSize(400, 400);
fr.setVisible(true);
}
}
Then, whenever I press the button, the other thread wakes up, executes one round and waits for a new clicking.
The java primitive to suspend and resume a thread is deprecated. See this to figure how you can achieve best what you need - http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Check how you can do the equivalent of suspend & resume
What should I use instead of Thread.suspend and Thread.resume?
As with Thread.stop, the prudent approach is to have the "target thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify.
Example code is given in the same answer to help you achieve this.