Can anybody please provide me a good small example demonstrate wait() and notify() functionality in java. I've tried with the below piece of code but it's not showing what i expected.
public class WaitDemo {
int i = 10;
int display() {
System.out.println("Lexmark");
i++;
return i;
}
}
public class ClassDemo1 extends Thread {
private WaitDemo wd = new WaitDemo();
public static void main(String[] args) {
ClassDemo1 cd1 = new ClassDemo1();
ClassDemo1 cd2 = new ClassDemo1();
cd1.setName("Europe");
cd2.setName("America");
cd1.start();
cd2.start();
}
synchronized void display() {
System.out.println("Hello");
notifyAll();
}
public void run() {
synchronized (this) {
try {
{
notify();
System.out.println("The thread is " + currentThread().getName());
wait();
System.out.println("The value is " + wd.display());
}
} catch (InterruptedException e) {
}
}
}
}
The issue is that the method in the class WaitDemo is not getting executed and as per my idea the SOP after wait() should execute. Please help me out on this.
You've got two levels of braces { in your try block. If you remove the inner set (which doesn't appear to do anything), does that fix the problem?
There are several examples around, all of which demonstrate the use. The last link is a set of results that can help you out. If you need more specific things, let me know what it is that your app is trying to do, and I can try to find examples that are more specific to your situation.
http://www.javamex.com/tutorials/wait_notify_how_to.shtml
http://www.java-samples.com/showtutorial.php?tutorialid=306
http://www.coderanch.com/t/234235/threads/java/Wait-Example
https://www.google.com/search?q=wait%28%29+example+java&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
Below is an example of wait & notify in the Object class. The customer is trying to withdraw money of value 2000 but the account is having only 1000 so it has to wait for the deposit. Once the deposit is made, then the customer will be able to withdraw the amount. Until the deposit is made, the customer will be waiting.
class Cust {
private int totalAmount = 1000;
public synchronized void withdrawal(int amount) {
System.out.println("Total amount " + totalAmount + " withdrawing amount " + amount);
while (this.totalAmount < amount) {
System.out.println("not enough amount..waiting for deposit..");
try { wait(); } catch (Exception e) {}
}
this.totalAmount -= amount;
System.out.println("Withdrawal successful.. Remaining balance is "+totalAmount);
}
public synchronized void deposit(int amount){
System.out.println("Depositing amount "+amount);
this.totalAmount += amount;
System.out.println("deposit completed...and Now totalAmount is " + this.totalAmount);
notify();
}
}
class Depo implements Runnable {
Cust c; int depo;
Depo(Cust c, int depo){
this.c = c;
this.depo = depo;
}
#Override
public void run() {
c.deposit(depo);
}
}
class Withdrawal implements Runnable {
Cust c; int with;
Withdrawal(Cust c, int with){
this.c = c;
this.with = with;
}
#Override
public void run() {
c.withdrawal(with);
}
}
public class ObjectWaitExample {
public static void main(String[] args) {
Cust c = new Cust();
Thread w = new Thread(new Withdrawal(c, 2000));
Thread d1 = new Thread(new Depo(c, 50));
Thread d2 = new Thread(new Depo(c, 150));
Thread d3 = new Thread(new Depo(c, 900));
w.start();
d1.start();
d2.start();
d3.start();
}
}
I created two threads one for printing odd numbers (OddThread) and another for even numbers (EvenThread). Inside the run method of each of the threads I used the shared object of class Print to call printOdd() and printEven() for the Odd and EvenThread respectively. I made the shared object of Print static so that only one copy is made. Now synchronizing on the Print object I used a Boolean flag such that when the odd thread printed an odd number it will be sent into the waiting state and the at the same time notifying the even thread to execute. The logic is written in such a way that the odd thread will always print the odd number first no matter what, as the flag is set to false initially preventing the even thread to execute and sending it to a waiting state.
package com.amardeep.test;
public class ThreadDemo {
// Shared object
static Print print = new Print();
public static void main(String[] args) {
new Thread(new OddThread()).start();
new Thread(new EvenThread()).start();
}
}
class EvenThread implements Runnable {
#Override
public void run() {
ThreadDemo.print.printEven();
}
}
class OddThread implements Runnable {
#Override
public void run() {
ThreadDemo.print.printOdd();
}
}
class Print {
public volatile boolean flag = false;
public synchronized void printEven() {
for (int i = 1; i <= 10; i++) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
if (i % 2 == 0) {
System.out.println("from even " + i);
flag = false;
notifyAll();
}
}
}
}
public synchronized void printOdd() {
for (int i = 1; i <= 10; i++) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
if (i % 2 != 0) {
System.out.println("from odd " + i);
flag = true;
notifyAll();
}
}
}
}
}
output:-
from odd 1
from even 2
from odd 3
from even 4
from odd 5
from even 6
from odd 7
from even 8
from odd 9
from even 10
Your problem is that you are creating two instances of the Thread class. Thus when the wait() is called, it is on two different instances, neither of which has another thread that is in contention for your monitor, nor is there another thread to call notifyAll() to wake the thread from its wait state.
Thus each thread you have started will wait forever (or until interrupted for some other reason).
You want to have multiple threads accessing the same monitor, so start by trying to code something in which the code in question is not actually a thread, but is simply being used by a thread.
#normalocity has already provided links to multiple examples.
I just updated this answer to include an SCCE.
The workers call pauseIfNeeded on the WorkerPauseManager. If the manager is paused when the worker thread calls pauseIfNeeded(), we call wait(), which tells the calling thread to wait until a different thread calls notify() or notifyAll() on the object being waited on. This happens when the Swing Event Dispatch Thread calls play() on the manager, which in turn calls notifyAll().
Note that you must have a synchronized lock on the object you are calling wait() or notify() on. Since the methods in WorkerPauseManager are synchronized, all the synchronized methods are getting a synchronized lock on the WorkerPauseManager itself.
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* #author sbarnum
*/
public class WorkerPauseManagerTest {
public static void main(String[] args) {
final WorkerPauseManager pauseManager = new WorkerPauseManager();
new Worker("Worker 1", pauseManager).start();
new Worker("Worker 2", pauseManager).start();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JToggleButton playPauseButton = new JToggleButton(new AbstractAction("Pause") {
public void actionPerformed(final ActionEvent e) {
JToggleButton source = (JToggleButton) e.getSource();
if (source.isSelected()) {
pauseManager.start();
source.setText("Pause");
} else {
pauseManager.pause();
source.setText("Play");
}
}
});
playPauseButton.setSelected(true); // already running
JOptionPane.showMessageDialog(null, playPauseButton, "WorkerPauseManager Demo", JOptionPane.PLAIN_MESSAGE);
System.exit(0);
}
});
}
private static class Worker extends Thread {
final String name;
final WorkerPauseManager pauseManager;
public Worker(final String name, final WorkerPauseManager pauseManager) {
this.name = name;
this.pauseManager = pauseManager;
}
#Override
public void run() {
while (!Thread.interrupted()) {
try {
pauseManager.pauseIfNeeded();
System.out.println(name + " is running");
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static final class WorkerPauseManager {
private boolean paused;
public synchronized void pauseIfNeeded() throws InterruptedException {
if (paused) wait();
}
public synchronized void pause() {
this.paused = true;
}
public synchronized void start() {
this.paused = false;
notifyAll();
}
}
}
What wait method does is , when some thread executed a synchronized block by locking some object (we call that object is "a") , then inside that synchronized block when the thread executed the wait method of object "a" like this
A a = new A (); // some class object call "a"
synchronized (a){
a.wait ();//exceptions must be handled
}
Then the a object will release and the thread has to go to the wait state until it has been release from that state.
and anothet thread now can use the a object beacause its a release object. so if another thread locked that object and it executed the notify method from that object like
a.notify ()
Then one of a thread of the threads that went to wait state by object "a" can be released from the wait state. Other wise when call the notifyAll then the all the thread objects will release from that state.
/*
* the below program is like
* tread t1 will first run , and it comes to "notify()" method
* there are no threds waiting bcoz this is the first thread.
* so it will not invoke any other threads. next step is "wait()" method
*will be called and the thread t1 in waiting state. next stament
* "System.out.println("The value is ..."+wd.display());" will not be executed
* because thread t1 is in waiting state.
*
* thread t2 will run ,and it comes to "notify()" method ,there is already
* thread t1 is in waiting state ,then it will be invoked.now thread t1 will
* continue execution and it prints the statement "System.out.println("The value is ..."+wd.display())"
* and thread t2 will be in waiting state now.
*
* if you uncomment "notifyAll()" method then, after t1 thread completes its execution
*then immediately "notifyAll()" method will be called,by that time thread t2 is
* already in waiting state , then thread t2 will be invoked and continues execution.
*or
* if any other threadds are in waiting state all those threads will be invoked.
*/
package threadsex;
/**
*
* #author MaheshM
*/
/**
* #param args the command line arguments
*/
public class WaitNotifyNotifyAllDemo implements Runnable {
WaitDemo wd = new WaitDemo();
public static void main(String[] args) {
WaitNotifyNotifyAllDemo cd1 = new WaitNotifyNotifyAllDemo();
Thread t1 = new Thread(cd1);
t1.setName("mahi1");
Thread t2 = new Thread(cd1);
t2.setName("mahi2");
t1.start();
t2.start();
}
#Override
public void run() {
synchronized (this) {
try {
System.out.println("The thread is=" +
Thread.currentThread().getName());
notify();
wait();
System.out.println("The value is ..." + wd.display());
// notifyAll();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
Related
I have a class named "Clock" which have implementing Runnable. In run() a infinite loop is started where thread sleeps for 100ms for each iteration and then changes a boolean value :"isOk".
There is another class "ConOne" in its seperate thread also having infinite loop and it tries to get the "isOk" boolean value from "Clock" class. but if value is false then "ConOne" has to wait at the thread to continue.
So I created to ConOne objects trying to access the boolean value from "Clock" class.
But it thorws a Exception describing that "current object is not a owner of thread".
Why is this happening?
And sorry for my English.
Here's code:
Clock class
public class Clock implements Runnable {
boolean isOk;
Thread t;
Clock() {
isOk = false;
t = new Thread(this, "Clock_Thread");
}
void startClock() {
t.start();
}
public void run() {
int i = 0;
while(true) {
try {
t.sleep(100);
System.out.println("Tick:" + i);
if(isOk) {
isOk = false;
} else {
isOk = true;
notify();
}
i++;
} catch(InterruptedException ie) {
System.out.println("InterruptedException at Clock");
}
}
}
public boolean getPermit() {
if (!isOk) {
try {
wait();
} catch(InterruptedException e) {
System.out.println("Exception at clock.getPermit()");
}
}
return true;
}
}
ConOne class:
public class ConOne implements Runnable {
Thread t;
Clock ct;
ConOne(String name, Clock c) {
t = new Thread(this, name);
ct = c;
}
public void run() {
while(true) {
ct.getPermit();
repaint();
}
}
public void repaint() {
System.out.println("Repainted On " + t);
}
}
Class with main method:
public class Master {
public static void main(String[] args) {
Clock clock = new Clock();
ConOne con1 = new ConOne("Con11", clock);
ConOne con2 = new ConOne("Con12", clock);
clock.startClock();
con1.t.start();
con2.t.start();
}
}
Here is the error:
Error Screenshot
You can only call a wait on an object, if you have synchronized on that object.
So something like this:
synchronized(monitor){
while(!condition)
monitor.wait();
}
You’ve got things a bit twisted up I’m afraid, the notify() and wait() require ownership of the Clock object’s monitor. You can try to get the wait/notify semantics correct, but I recommend just using builtin tools, specifically a SynchronizedQueue. Clock can just hold one as a field and put 1 into it when isOk. The other thread can be put into a non-busy wait() with a simple take() from the queue, which will block until the Clock class puts something.
Here is the code snippet:
public class PrintEvenOdd
public static class SynchronizedThreadMonitor {
public final static boolean ODD_TURN = true;
public final static boolean EVEN_TURN = false;
private boolean turn = ODD_TURN;
public synchronized void waitTurn(boolean oldTurn) {
while (turn != oldTurn) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException in wait(): " + e);
}
}
}
public synchronized void toggleTurn(){
turn ^= true;
notify();
}
}
public static class OddThread extends Thread {
private final SynchronizedThreadMonitor monitor;
public OddThread(SynchronizedThreadMonitor monitor) {
this.monitor = monitor;
}
#Override
public void run() {
for (int i=1; i<=100; i+=2) {
monitor.waitTurn(SynchronizedThreadMonitor.ODD_TURN);
System.out.println("i= " + i);
monitor.toggleTurn();
}
}
}
public static class EvenThread extends Thread {
private final SynchronizedThreadMonitor monitor;
public EvenThread(SynchronizedThreadMonitor monitor) {
this.monitor = monitor;
}
#Override
public void run() {
for (int i=2; i<=100; i+=2) {
monitor.waitTurn(SynchronizedThreadMonitor.EVEN_TURN);
System.out.println("i= " + i);
monitor.toggleTurn();
}
}
}
public static void main(String[] args) throws InterruptedException {
SynchronizedThreadMonitor monitor = new SynchronizedThreadMonitor();
Thread t1 = new OddThread(monitor);
Thread t2 = new EvenThread(monitor);
t1.start();
t2.start();
t1.join();
t2.join();
}
}
Using 2 threads to print numbers. One prints odd numbers and another prints even numbers.
In my understanding, both waitTurn and toggleTurn share the same LOCK of the instance. So if one holds the LOCK, the other method could not run. So if EvenThread first invokes waitTurn method and wait for the turn change, it holds the LOCK, then OddThread could not enter the toggleTurn method and set the turn. This should lead to a deadlock as per my understanding. But it did not happen.
Can someone please explain why the deadlock did not happen?
"So IF EvenThread first run waitTurn method and wait for the turn change, it holds the LOCK, the OddThread could NOT enter the toggleTurn method"
It holds the LOCK only small period of time, until method wait() is invoked. Method wait() releases the LOCK and allows another thread to enter the critical section.
I am trying to work around with threads in java. Though I understand that threads output are unpredictable, However was wondering if there is a way to do that.
I have to implement two threads, one prints alphabets(a,b,c...z) and other prints numbers(1,2,3....26). Have to implement it in such a way that the output should be a,1,b,2,c,3,d,4......z,26. Below is my code but it doesn't give the desired output.
public class ThreadsExample {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
System.out.print(i+",");
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
System.out.print(i+",");
}
}
}
What tweak should I make in the code to get the desired output? How does synchronization helps here? Or is it really possible when working with Threads at all?
PS: This is not an assignment or some exercise. Its self learning.
It is possible. You need to synchronize it well.
Approach Pseudocode
query some (synchronized) state
state will tell whether nums or chars are allowed
if state allows char and caller will put chars, do it now and change state and wake up waiting threads
if not, wait
if state allows numbers and caller will put numbers, do it now and change state and wake up waiting threads
if not, wait
Java code
public class ThreadsExample {
public static ThreadsExample output = new ThreadsExample ();
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
private Object syncher = new Object (); // we use an explicit synch Object, you could use annotation on methods, too. like ABHISHEK did.
// explicit allows to deal with more complex situations, especially you could have more the one locking Object
private int state = 0; // 0 allows chars, 1 allows ints
public void print (char pChar) {
synchronized (syncher) { // prevent the other print to access state
while (true) {
if (state == 0) { // char are allowed
System.out.print(pChar + ","); // print it
state = 1; // now allow ints
syncher.notify(); // wake up all waiting threads
return;
} else { // not allowed for now
try {
syncher.wait(); // wait on wake up
} catch (InterruptedException e) {
}
}
}
}
}
public void print (int pInt) {
synchronized (syncher) {
while (true) {
if (state == 1) {
System.out.print(pInt + ",");
state = 0;
syncher.notify();
return;
} else {
try {
syncher.wait();
} catch (InterruptedException e) {
}
}
}
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
ThreadsExample.output.print(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
ThreadsExample.output.print(i);
}
}
}
Output
a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i,9,j,10,k,11,l,12,m,13,n,14,o,15,p,16,q,17,r,18,s,19,t,20,u,21,v,22,w,23,x,24,y,25,z,26,
The whole idea of threads: it represents a "stream of activity" that executes code independent of other threads.
In your case, you want that these two threads go in "lockstep". Thread A does one step, then Thread B, then A, then B.
In order to get there, the two threads need something "synchronize" on - in other words: A sends a signal to B when it has done its steps - and B has to wait for that signal. Then B does its thing, signals to A, ...
For starters, a simple boolean value would do. One thread sets it to true, the other to false (to indicate when it has made its step). Then the thread waits for the boolean to toggle again.
As you intend to learn things, I would just start experimenting from there. In case you want to take detours, look here for example. This might help as well.
HERE IS THE CODE::
You need to create 2 threads and implement wait and notify methods correctly you can also refer "Create two threads, one display odd & other even numbers" for your answer.
public class ThreadClass {
volatile int i = 1;
volatile Character c = 'a';
volatile boolean state = true;
synchronized public void printAlphabet() {
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " +c);
state = false;
c++;
notifyAll();
}
synchronized public void printNumbers() {
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
state = true;
i++;
notifyAll();
}
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread() {
int k = 0;
#Override
public void run() {
while (k < 26) {
threadClass.printAlphabet();
k++;
}
}
};
t1.setName("Thread1");
Thread t2 = new Thread() {
int j = 0;
#Override
public void run() {
while (j < 26) {
threadClass.printNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Your threads are running at the same time. But not the way you want it, as mentioned above. You will see blocks of data from thread 1 and then a block of data from thread 2; and this is because of thread scheduling. Thread 1 is just queuing its output before thread 2.
To test this theory, increase your output to a 1000 records for example as the alphabet and 26 numbers are not as large to see this.
By doing so, you will see these 'blocks' of data. There is a way to do what you mentioned, but it is not advisable as this is not demonstrating how threads actually work but rather you forcing it to work that way.
With less Code:
class MyRunnable implements Runnable {
private static int n = 1;
private static char c = 'a';
public void run() {
for (int i = 1; i <= 26; i++) {
synchronized (this) {
try {
notifyAll();
if (Thread.currentThread().getName().equals("A")) {
System.out.print(c + ",");
c++;
} else {
System.out.print(n + ",");
n++;
}
if (i != 26) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintAlphabetNumberJob {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread tAlphabet = new Thread(r, "A");
Thread tNumber = new Thread(r, "N");
tAlphabet.start();
Thread.sleep(100);
tNumber.start();
}
}
I am trying to print numbers from 1 to 10 using three threads. thread 1 prints 1, 2 prints 2, 3 prints 3, 4 is printed by thread 1 again and so on.
I have created a shared printer resource that helps those threads to print number. But I am getting confused as how can i make the number to be visible by all threads.
The problem is eachthread is seeing their own copy of number while I need the same number to be shared by all threads.
I am trying to create this example for learning purposes. I have seen other pages on SO that had same kind of problem but I am not able to get the concept.
Any help is appreciated.
how is this example diffrent from what I am doing?
Printing Even and Odd using two Threads in Java
public class PrintAlternateNumber {
public static void main(String args[]) {
SharedPrinter printer = new SharedPrinter();
Thread t1 = new Thread(new myRunnable2(printer,10,1),"1");
Thread t2 = new Thread(new myRunnable2(printer,10,2),"2");
Thread t3 = new Thread(new myRunnable2(printer,10,3),"3");
t1.start();
t2.start();
t3.start();
}
}
class myRunnable2 implements Runnable {
int max;
SharedPrinter printer;
int threadNumber;
int number=1;
myRunnable2(SharedPrinter printer,int max,int threadNumber) {
this.max=max;
this.printer=printer;
this.threadNumber=threadNumber;
}
#Override
public void run() {
System.out.println(" The thread that just entered run "+ Thread.currentThread().getName());
for(int i =1;i<max;i++){
try {
printer.print(i,threadNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class SharedPrinter {
boolean canPrintFlag=false;
public synchronized void print(int number,int threadNumber) throws InterruptedException{
if(number%3==threadNumber) {
canPrintFlag=true;
}
while(!canPrintFlag)
{
System.out.println(Thread.currentThread().getName() + " is waiting as it cannot print " + number);
wait();
}
System.out.println(Thread.currentThread().getName()+" printed "+number);
canPrintFlag=false;
notifyAll();
}
}
//output
//The thread that just entered run 2
// The thread that just entered run 3
//The thread that just entered run 1
//3 is waiting as it cannot print 1
//1 printed 1
//1 is waiting as it cannot print 2
//3 is waiting as it cannot print 1
//2 is waiting as it cannot print 1
Technique second
it is still incomplete but I am close
output
0printed by0
2printed by2
1printed by1
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
class AlternateNumber {
public static void main(String args[]) {
printerHell ph = new printerHell();
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);
for(int i=0;i<10;i++)
{
queue.add(i);
}
Thread t1 = new Thread(new myRunnableHell(queue,0,ph),"0");
Thread t2 = new Thread(new myRunnableHell(queue,1,ph),"1");
Thread t3 = new Thread(new myRunnableHell(queue,2,ph),"2");
t1.start();
t2.start();
t3.start();
}
}
class myRunnableHell implements Runnable {
BlockingQueue<Integer> queue;
int threadNumber;
printerHell ph;
myRunnableHell(BlockingQueue<Integer> queue, int threadNumber,printerHell ph) {
this.queue=queue;
this.threadNumber=threadNumber;
this.ph=ph;
};
int currentNumber;
#Override
public void run() {
for(int i=0;i<queue.size();i++)
{
currentNumber=queue.remove();
if(threadNumber%3==currentNumber)
{
ph.print(currentNumber);
}
}
}
}
class printerHell {
public synchronized void print(int Number)
{
System.out.println(Number + "printed by" + Thread.currentThread().getName());
}
}
Please see my solution here..
Using simple wait/notify
https://stackoverflow.com/a/31668619/1044396
Using cyclic barriers:
https://stackoverflow.com/a/23752952/1044396
For your query on 'How different it is from even/odd thread problem.
--> it is almost same ... instead of maintaining two states have one more state to call the third thread, so I believe,this can be extended any number of threads.
EDIT:
You may view this approach when you want to have 'n' number of threads to do the work sequentially.(Instead of having different classes t1,t2,t3 etc)
https://codereview.stackexchange.com/a/98305/78940
EDIT2:
Copying the code here again for the above solution
I tried to solve using a single class 'Thrd' which gets initialized with its starting number.
ThreadConfig class which as size of total number of threads you want to create.
State class which maintains the state of the previous thread.(to maintain ordering)
Here you go..(please review and let me know your views)
EDIT:
How it works -->
when a thread Tx gets a chance to execute.. it will set state variable's state with x. So a next thread(Tx+1) waiting , will get a chance once state gets updated. This way you can maintain the ordering of threads.
I hope i am able to explain the code. Please run it and see or let me know for any specific queries on the below code
1)
package com.kalyan.concurrency;
public class ThreadConfig {
public static final int size = 5;
}
2) package com.kalyan.concurrency;
public class State {
private volatile int state ;
public State() {
this.state =3;
}
public State(int state) {
this.state = state;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
3) package com.kalyan.concurrency;
public class Thrd implements Runnable {
int i ;
int name;
int prevThread;
State s;
public Thrd(int i,State s) {
this.i=i;
this.name=i;
this.prevThread=i-1;
if(prevThread == 0) prevThread=ThreadConfig.size;
this.s=s;
}
#Override
public void run() {
while(i<50)
{
synchronized(s)
{
while(s.getState() != prevThread)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==prevThread)
System.out.println("t"+ name+ i);
s.setState(name);
i = i +ThreadConfig.size ;
s.notifyAll();
}
}
}
}
4)
package com.kalyan.concurrency;
public class T1t2t3 {
public static void main(String[] args) {
State s = new State(ThreadConfig.size);
for(int i=1;i<=ThreadConfig.size;i++)
{
Thread T = new Thread(new Thrd(i,s));
T.start();
}
}
}
OUTPUT:
t11
t22
t33
t44
t55
t16
t27
t38
t49
t510
t111
t212
t313
t414
t515
t116..............
I hope I understood you right, but there are to main "features" in java to make a variable being shared between threads:
the volatile keyword
volatile int number = 1;
AtomicInteger (a standard java class -> no library)
AtomicInteger number = new AtomicInteger(1);
These two techniques should both do what you want, however I have no experience using it, I just came upon this word, didn't know what it means and did some digging.
Some stuff to read: ;)
volatile for java explained --> http://java.dzone.com/articles/java-volatile-keyword-0
a better explanation (with IMAGES!!) but for c# (which is still the same usage) --> http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/
And a link to some usages of AtomicInteger --> https://stackoverflow.com/a/4818753/4986655
I hope I could help you or at least send you in the right direction :)
- superfuzzy
I am trying to generate Odd/Even numbers using 2 threads using wait notify.
But It is just printing 1.
Below is the code:
Even.java
public class Even implements Runnable {
private int i; private Object ob
public Even(int i,Object o) {
this.i=i;
this.ob=o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (i % 2 == 0) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i++;
System.out.println(i);
ob.notifyAll();
}
}
}
}
Odd.java
public class Odd implements Runnable {
private int i; private Object ob;
public Odd(int i) {
this.i=i;
this.ob=o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (i % 2 == 1) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i++;
System.out.println(i);
ob.notifyAll();
}
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
int i = 0;
Object lock = new Object();
Thread t1 = new Thread(new Even(i),lock);
Thread t2 = new Thread(new Odd(i),lock);
t1.start();
t2.start();
}
}
Output:
1
Can anyone tell me where I am making the mistake?
Hmm, I would assume that it could be a problem that Integer appears to be immutable in Java. Thus you will not synchronize on the same objects anymore, if one of the two classes changed the i value (which it apparently does since the first output is 1).
So since you change the value stored in i in Odd and call notifyAll on the new object I that Java will complain since you call notifyAll on an object that actually never has been locked.
The threads have fallen into INDEFINITE WAITING state. Note that (t1 i.e instance of Even and t2 i.e instance of Odd), each have a separate copy of instance variable i.
Here is whats going on behind the scenes:
Initially, both thread t1 (Even) and t2 (Odd) are in READY and then RUNNABLE state
Lets assume t1 is scheduled and gets processor to execute. t1 enters RUNNING state. t1's run() is invoked
while(true) succeeds and control enters outer while loop
because of synchronized(ob) t1 locks object ob
since i is 0 initially; i % 2 == 0 condition evaluates to true
control now enters body of inner while loop, then try block and invokes ob.wait();
t1 enters WAITING state and waits until someone notifies on object ob
Now, t2 is scheduled and gets processor to execute. t2 enters RUNNING state
while(true) succeeds and control enters outer while loop
because of synchronized(ob) t2 locks object ob
i is 0 initially (remember the i incremented previously was local to t1 - Even.i). The variable i in this context is local to t2 i.e. Odd.i.
Hence i % 2 == 1 evaluates to false and control skips inner while loop
Control reaches i++; i is incremented from 0 to 1
The statement System.out.println(i); prints 1 to console
contorl moves to next line and ob.notifyAll(); is invoked and all the threads waiting on object ob (t1 in our case) are notified
At this point, both t1 and t2 are back in RUNNABLE state again
Depends on processor which thread to schedule
Lets assume t1 is scheduled and gets processor to execute
t1 resumes its operations from where it left previously (i.e the statement after ob.wait();)
control reaches catch (InterruptedException e) and since there is no exception, its skipped and control comes back to while ( i % 2 == 0) check
Remember, t1's i (i.e Even.i) is still 0 because control din't reach the line i++; in Even class
Hence i % 2 == 0 evaluates to true and control enters into body of while loop, then enters the try block and invokes ob.wait();
t1 enters WAITING state again and waits until someone notifies on object ob
Now, t2 is scheduled and gets processor to execute. t2 enters RUNNING state
t2 resumes its operations from where it left previously (i.e the statement after ob.notifyAll();)
since there is no other statement after ob.notifyAll();, the control reaches outer while loop
while(true) is evaluated and control enters body of outer while loop
because of synchronized(ob) t1 locks object ob
Remember t2's i is now 1 because it was incremented previously and printed on console
Hence, while ( i % 2 == 1) is evaluated to true and control enters body of inner while loop, then try block and invokes ob.wait();
As a result, t2 enters WAITING state
t1 and t2 are both in WAITING state now; waiting on object ob. Waiting for someone to notify them on object ob. Sadly, there is no one to rescue
Hence the INDEFINITE WAITING
Following code should help in what you are trying to achieve
public class EvenOddTest {
public static void main(String[] args) {
Lock lock = new Lock();
Thread t1 = new Thread(new Even(lock));
Thread t2 = new Thread(new Odd(lock));
t1.start();
t2.start();
}
}
class Lock {
private int data;
public void increment() {
data++;
}
public int getData() {
return data;
}
}
class Even implements Runnable {
private Lock ob;
public Even(Lock o) {
this.ob = o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (ob.getData() % 2 == 0) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ob.increment();
System.out.println(ob.getData());
ob.notifyAll();
}
}
}
}
class Odd implements Runnable {
private Lock ob;
public Odd(Lock o) {
this.ob = o;
}
#Override
public void run() {
while (true) {
synchronized (ob) {
while (ob.getData() % 2 == 1) {
try {
ob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ob.increment();
System.out.println(ob.getData());
ob.notifyAll();
}
}
}
}
Note:
I have refactored your code so that the object on which threads try to obtain lock and wait upon, holds the data as well.
lock object is now the shared instance between Even and Odd threads.
With my previous reasoning, the code should be self explanatory.
This is not actual way of doing things in parallel computing, to leverage multi-threading power/capabilities. However, it should be a good starter exercise.
You can put i variable as a class attribute in Test class, then create an object of type Test and pass it as parameter to the constructors:
public class Test {
public Integer i = 0;
public static void main(String[] args) {
Object o = new Object();
Test t = new Test();
Thread t1 = new Thread(new Even(t,o));
Thread t2 = new Thread(new Odd(t,o));
t1.start();
t2.start();
}
}
public class Even implements Runnable {
private Test t;
private Object o;
public Even(Test t, Object o) {
this.t=t;
this.o=o;
}
#Override
public void run() {
while (true) {
synchronized (o) {
while (t.i % 2 == 0) {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t.i++;
System.out.println(t.i);
o.notifyAll();
}
}
}
}
public class Odd implements Runnable {
private Test t;
private Object o;
public Odd(Test t, Object o) {
this.t=t;
this.o = o;
}
#Override
public void run() {
while (true) {
synchronized (o) {
while (t.i % 2 == 1) {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t.i++;
System.out.println(t.i);
o.notifyAll();
}
}
}
}