I am trying to print numbers from 1 to 10 in sequence using a shared integer object across multiple threads. When using the shared object as AtomicInteger, the program works correctly, but when using normal Integer objects, the program throws an exception and I don't know why this is happening.
Program with AtomicInteger
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadingProblem {
public static void main(String[] args) {
AtomicInteger sharedInt = new AtomicInteger(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingPrintingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private AtomicInteger sharedObject;
public ThreadingIncrementingTask(AtomicInteger sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject.get() < 10) {
this.sharedObject.incrementAndGet();
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output
Shared object value is: 1
Shared object value is: 2
Shared object value is: 3
Shared object value is: 4
Shared object value is: 5
Shared object value is: 6
Shared object value is: 7
Shared object value is: 8
Shared object value is: 9
Shared object value is: 10
Program with normal Integer object
public class ThreadingProblem {
public static void main(String[] args) {
Integer sharedInt = new Integer(0);
Thread t1 = new Thread(new ThreadingPrintingTask(sharedInt), "PrinterThread");
Thread t2 = new Thread(new ThreadingIncrementingTask(sharedInt), "IncrementerThread");
t1.start();
t2.start();
}
}
class ThreadingPrintingTask implements Runnable {
private Integer sharedObject;
public ThreadingPrintingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
try {
synchronized (sharedObject) {
while (true) {
sharedObject.wait();
System.out.println("Shared object value is: " + sharedObject);
sharedObject.notify();
}
}
}
catch (InterruptedException e) {
}
}
}
class ThreadingIncrementingTask implements Runnable {
private Integer sharedObject;
public ThreadingIncrementingTask(Integer sharedObject) {
this.sharedObject = sharedObject;
}
#Override
public void run() {
synchronized (sharedObject) {
while (this.sharedObject < 10) {
this.sharedObject++;
this.sharedObject.notify();
try {
this.sharedObject.wait();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output
Exception in thread "IncrementerThread" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.itiviti.apps.catalys.shared.mock.ThreadingIncrementingTask.run(ThreadingProblem.java:52)
at java.lang.Thread.run(Unknown Source)
this.sharedObject++; does not do what you assumed it would do.
Since Integer is immutable, it can't change the existing shared object. What this operation does instead is unbox the value into an int, increment it, then box it back into a different Integer instance.
So your code is (almost*) equivalent to the following:
int temp = this.sharedObject.intValue();
temp = temp + 1;
this.sharedObject = new Integer(temp);
As at this point your object is no longer the same instance, your synchronized blocks won't line up with the wait()/notify() calls.
Note that this has got nothing to do with the atomicity of AtomicInteger, it's simply to do with how the ++ operator works on an Integer.
*In reality you might get a cached instance instead of new Integer(), but it will still be a different instance, as it represents a different int value.
Related
This question already has answers here:
Java Wait and Notify: IllegalMonitorStateException
(2 answers)
Closed 4 years ago.
Was trying to practice producer and consumer using a simple counter in java.
Not sure why I am getting a Illegal Monitor State exception on this piece of code.
I have counter rest and counter consume methods which run in their own thread.
The counter itself is a static int volatile field .
The counter class also gives you a lock to
If I change the wait naotify to the following:
Counter.lock.notify();
Counter.lock.wait();
The code works. Dosen't wait() and notify() automatically takes the reference of the lock synchronize is on?
Producer Class
package multithreading;
public class CounterProducer implements Runnable {
public void run() {
try { incrCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void incrCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter < 1) {
System.out.println("Counter Reset");
Counter.counter = 10;
notify();
wait();
}
}
}
}
}
Consumer Class
package multithreading;
public class CounterConsumer implements Runnable {
public void run() {
try { consumeCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void consumeCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter > 0) {
System.out.println("Consumed");
Counter.counter--;
notify();
wait();
}
}
}
}
}
The Counter
public class Counter {
public static volatile int counter;
public static final Object lock = new Object();
}
The Counter
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
The Runner
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
If I change the wait naotify to the following, the code works:
Counter.lock.notify();
Counter.lock.wait();
Every Java method is either a static method of some class or an instance method of some object. If you see a method call that does not contain an explicit class name or object reference, then it is an implicit call to a method belonging to the this object.
That is to say, notify() means the same thing as this.notify(), and wait() means this.wait().
this, refers to the CounterProducer instance when it appears in your CounterProducer.incrCounter() method, and it refers to the CounterConsumer instance when it appears in your CounterConsumer.consumeCounter() method.
I have two threads. The first changes the value of variable Data. And second one print the value if its value has changed. I am trying to do that second thread just print each time that the variable's value changed, but I don't reach success. Someone can help me?
thread 1
class someservice{
volatile int data;
Boolean Flag = false;
public void mymethod(){
flag = true;
for (Integer i = 1; i < sheet.getRows(); i++) {
data = someMethod(); //this method when called return a new
//value
}
flag = false;
...
}
}
thread 2
Promise p = task {
try {
while (true) {
if (engineService.getFlag()) {
print(someservice.data);
}else{
break;
}
}
} catch(Throwable t) {
...
}
}
Since you mention Promises, I infer you are familiar with future/ promise in +C++11
in java there is a similar approach, with future callable...
public class HW5 {
public static void main(String[] argv) throws InterruptedException, ExecutionException {
FutureTask<Boolean> myFutureTask = new FutureTask<>(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
// implement the logic here and return true if everything was
// ok, false otherwise.
Thread.sleep(5000);
System.out.println("dddd");
return System.currentTimeMillis() % 2 == 0;
}
});
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(myFutureTask);
Boolean result = myFutureTask.get();
System.out.println("Done!");
}
}
FutureTask in a class that takes a callable which can return an Object after its job is done... in Order to execute the Future task you can use a Executor service, especifically calling the method execute, since you need to wait for the thread to do the job then is necessary that you call Future.get, that will basically blocks the main thread until the future is done, to verify the result, just read the variable result..
You could use the notify() and notifyAll() methods within thread. Check out this link: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
You have to look up more data about Concurrent programming,I can tell you now some basics,well,not so so basic,but i will do my best:
Here,you have a Monitor,it is an abstract concept,in resume,a Monitor is a
class with all it's
method using"syncronized"
as modifier, it means,
that only
one thread
can access
the method
at once.So,
in the
monitor is
the variable
that you
want to print,
and the"flag",
that tells you if
the variable
was modified.Finally,
you can
see the
most important thing,the"wait()"and"notify()"methods,
those method
stops the thread,or"play"
them again.
You ask
here in
the printValue() method, if your variable was changed, if the variable was'nt change, put the thead to sleep with the wait() method, and when the other
method changeValue() is executed, the value is modified, and the notify() method is called, waking up the thread, so, doing all this, you can guarantee three things:
Safety: meaning that the threads will do that you want
Absence of deadlock: meaning that the thread that is put to sleep, will be awake in the future.
Mutex: meaning that only one thread is executing the critical code, for example, the op. "++" is not atomic, is Subdivided inside in more the one action, create a local var, read the var, sum, and asign, so, if more than one thread are in the game, the value may not be consecutive, example:
i = 0;
i ++;
output: 1;
output: 2;
output: 3;
output: 5;
output: 4;
output: 7;
That could happen, and even so, that will happen in the next code, because there a more than one thread executing. Well, this is the way to program with several threads, more or less
public class Monitor {
private int value = 0;
public static boolean valueHasChanged = false;
public synchronized int changeValue(int newValue){
this.value = newValue;
Monitor.valueHasChanged = true;
this.notify();
return this.value + 1;
}
public synchronized void printValue(){
while(!Monitor.valueHasChanged){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(this.value);
Monitor.valueHasChanged = false;
}
public static void main(String[] args) {
Monitor ac = new Monitor();
BClass t1 = new BClass(ac);
AClass t2 = new AClass(ac);
t1.start();
t2.start();
}
public int getValue() {
return this.value;
}
}
Now the threads:
public class AClass extends Thread{
private Monitor ac;
public AClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.printValue();
}
}
}
And finally:
public class BClass extends Thread{
private Monitor ac;
public BClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
int v = 0;
while(true){
this.ac.changeValue(v);
v++; // this sum is not secure, if you want to print an
// ascending order, the code is diferent, I will show in
// above.
}
}
Now, if you want an ordered print:
the monitor will look like:
public class Monitor {
private int value = 0;
public boolean valueHasChanged = false;
private boolean hasPrint = true;
public synchronized void changeValue(int newValue) {
this.value = newValue;
this.valueHasChanged = true;
this.notify();
}
public synchronized void changeValuePlusOne() {
while (!hasPrint) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.value++;
this.valueHasChanged = true;
this.hasPrint = false;
this.notifyAll();
}
public synchronized void printValue() {
while (!this.valueHasChanged) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.value);
this.valueHasChanged = false;
this.hasPrint = true;
this.notifyAll();
}
public static void main(String[] args) {
Monitor ac = new Monitor();
BClass t1 = new BClass(ac);
AClass t2 = new AClass(ac);
t1.start();
t2.start();
}
public int getValue() {
return this.value;
}
}
And the Threads:
public class BClass extends Thread{
private Monitor ac;
public BClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.changeValuePlusOne();
}
}
}
The other Thread look equals:
public class AClass extends Thread{
private Monitor ac;
public AClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.printValue();
}
}
}
I have two threads. One is a producer (class Deliver), second is consumer (class Produce). I want to simulate door producer. So producer deliver wood that consumer can produce a door. But i do not real get how to communicate between those two threads. Now when i run my program only wood is delivered but doors are not produced. I do not get why.
public class Deliver implements Runnable {
private static int MAX_STOCKPILE = 15;
private Integer wood;
public Deliver(Integer wood) {
this.wood = wood;
new Thread(this, "Deliver").start();
}
public synchronized void deliver() throws InterruptedException{
Thread.sleep(500);
if (wood < MAX_STOCKPILE) {
wood++;
System.out.println("Wood delivered" + " | Wood stockpile: " + wood);
notify();
}
else {
wait();
}
}
#Override
public void run() {
while (true) {
try {
deliver();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Produce implements Runnable{
private Integer wood;
public Produce(Integer wood) {
this.wood = wood;
new Thread(this, "Produce").start();
}
public synchronized void produce() throws InterruptedException{
Thread.sleep(1000);
if (wood == 10) {
wood -= 10; //produce
System.out.println("Doors produced");
notify();
}
else {
wait();
}
}
#Override
public void run() {
while (true) {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Integer wood = 0;
new Deliver(wood);
new Produce(wood);
}
}
Now when i run my program only wood is delivered but doors are not produced. I do not get why
There are multiple issues with your code :
When you mark an instance method as synchronized, any thread entering that method will obtain a lock on this (i.e the instance on which the method was called). Since this in Deliver refers to a Deliver instance and this in Produce refers to a Produce instance, the wait and notify calls are practically useless in this case as they are not interested in the same objects.
The golden rule to remember in Java is that it uses pass-by-value semantics. Primitives and references are therefore always passed by value. While you may assume that both Deliver and Produce will be modifying the same Integer passed to them from main, that is not the case.
That said, I would highly recommend that you consider using something like an ArrayBlockingQueue for solving this instead of reinventing the wheel with wait and notify.
Change
if (wood == 10) {
to
if (wood >= 10) {
in case the thread doesn't catch it when it == 10
Something to note is that Integer is immutable.
When you change the reference to the Integer you are creating a new object which has no relationship to the previous object.
What you want this an object which is shared between the two threads so when you change the value (but not the reference) they are looking at the same value.
e.g.
wood -= 10;
is the same as
wood = Integer.valueOf(wood.intValue() - 10);
I suggest using AtomicInteger and making the reference to it final to ensure you don't accidentally try to change the reference.
As Andrew Jenkins suggests; if you lock, notify/wait on unrelated objects, you don't have any thread safety. Once you have a shared object, you have to lock, notify/wait on that shared object.
I'll throw my solution into the mix, taking into account Peter Lawrey's advice about using AtomicInteger.
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger wood = new AtomicInteger(0);
new Deliver(wood);
new Produce(wood);
}
}
public class Deliver implements Runnable {
private static int MAX_STOCKPILE = 15;
private final AtomicInteger wood;
public Deliver(AtomicInteger wood) {
this.wood = wood;
new Thread(this, "Deliver").start();
}
public void deliver() throws InterruptedException{
Thread.sleep(500);
synchronized(wood) {
if (wood.intValue() < MAX_STOCKPILE) {
wood.addAndGet(1);
System.out.println("Wood delivered" + " | Wood stockpile: " + wood);
wood.notify();
} else {
wood.wait();
}
}
}
#Override
public void run() {
while (true) {
try {
deliver();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Produce implements Runnable{
private final AtomicInteger wood;
public Produce(AtomicInteger wood) {
this.wood = wood;
new Thread(this, "Produce").start();
}
public void produce() throws InterruptedException{
synchronized(wood) {
if (wood.intValue() >= 10) {
wood.addAndGet(-10); //produce
System.out.println("Doors produced");
wood.notify();
}
else {
wood.wait();
}
}
}
#Override
public void run() {
while (true) {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Key changes:
We use a mutable object to communicate between threads (AtomicInteger).
We synchronize on the mutable object, not the thread being run.
I'm new to using wait() and notify() in Java and I'm getting an IllegalMonitorStateException.
Main Code
public class ThreadTest {
private static Integer state = 0;
public static void main(String[] args) {
synchronized(state) {
System.out.println("Starting thread");
Thread t = new Thread(new AnotherTest());
t.start();
synchronized(state) {
state = 0;
while(state == 0) {
try {
state.wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("State is: " + state);
}
}
}
public static class AnotherTest implements Runnable {
#Override
public void run() {
synchronized(state) {
state = 1;
state.notify();
}
}
}
}
I'm getting an IllegalMonitorStateException what state.notify() is called. Any ideas?
Edit: Based on answer below here is code that works. As a side note, I was first trying this with an enum which has the same problem of using Integer.
public class ThreadTest {
private static int state = 0;
private static Object monitor = new Object();
public static void main(String[] args) {
synchronized(monitor) {
System.out.println("Starting thread");
Thread t = new Thread(new AnotherTest());
t.start();
state = 0;
while(state == 0) {
try {
for(int i = 0; i < 5; i++) {
System.out.println("Waiting " + (5 - i) + " Seconds");
Thread.sleep(1000);
}
monitor.wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("State is: " + state);
}
}
public static class AnotherTest implements Runnable {
#Override
public void run() {
synchronized(monitor) {
state = 1;
monitor.notify();
}
}
}
}
This
private static Integer state = 0;
is equivalent to
private static Integer state = Integer.valueOf(0);
The invocation of valueOf(0) returns a reference to an Integer object, call it A.
You then do
synchronized(state) {
your thread acquires the lock on the object referenced by state, currently that is A.
You then do
state = 1;
which is equivalent to
state = Integer.valueOf(1);
which gives you a different reference to an Integer object, call it B, and assigns it to state. When you then call
state.notify();
you're invoking notify() on an object, B, for which your thread doesn't own the monitor. You can't call notify or wait on objects for which your thread doesn't own the monitor.
I'm trying to interleave the execution of two independent threads. such that both have a run method with 10 iterations and after every iteration i want to context switch the threads.
thread A starts and after doing something like printing passes control to thread B. then thread B prints and passes control back to A and so on until both finish.
What is the effective mechanism to do this?
I'm attaching a sample code. hope you can help.
// Suspending and resuming a thread for Java 2
class NewThread implements Runnable {
String name; // name of thread
Thread t;
// boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
// suspendFlag = false;
t.start(); // Start the thread
}
public String getState()
{
Thread t=Thread.currentThread();
return t.getState().toString();
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
//SuspendResume.suspendFlag2=false;
SuspendResume.suspendFlag1=true;
while(SuspendResume.suspendFlag1) {
wait();
//System.out.println(SuspendResume.ob1.t.getState().toString());
// if(SuspendResume.ob2.t.getState().toString()=="WAITING")
// SuspendResume.ob2.t.notify();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
// suspendFlag = true;
}
synchronized void myresume() {
// suspendFlag = false;
notify();
}
}
class NewThread2 implements Runnable {
String name; // name of thread
Thread t;
// boolean suspendFlag;
NewThread2(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
// suspendFlag = false;
t.start(); // Start the thread
}
public String getState()
{
Thread t=Thread.currentThread();
return t.getState().toString();
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
synchronized(this) {
//SuspendResume.suspendFlag1=false;
//while(SuspendResume.suspendFlag1) {
// while(suspendFlag) {
//wait();
//System.out.println(SuspendResume.ob2.t.getState().toString());
//if(SuspendResume.ob1.t.getState().toString()=="WAITING")
//SuspendResume.ob1.t.notify();
//}
SuspendResume.suspendFlag1=false;
notify();
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
// suspendFlag = true;
}
synchronized void myresume() {
// suspendFlag = false;
notify();
}
}
class SuspendResume {
static boolean suspendFlag1=false;
static NewThread ob1 = new NewThread("One");
static NewThread2 ob2 = new NewThread2("Two");
// static boolean suspendFlag2=false;
public static void main(String args[]) {
try {
//Thread.sleep(1000);
//ob1.mysuspend();
//System.out.println("Suspending thread One");
//Thread.sleep(1000);
//ob1.myresume();
//System.out.println("Resuming thread One");
// ob2.mysuspend();
//System.out.println("Suspending thread Two");
Thread.sleep(1000);
// ob2.myresume();
//System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
System.out.println(ob1.getState());
System.out.println(ob1.getState());
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
First off, I'm not sure what kind of scenario you have where you want to run two threads sequentially over and over again. That sounds like a single thread running two different methods in a loop. None-the-less, it sounds like an interesting challenge so I took it up.
Making use of Java 5's Exchanger class, the solution gets pretty small. I ended up with a single Runnable class. I use two instances of them to pass around a boolean true and boolean false to each other. The Exchanger class facilitates the passing around of the boolean values in a thread safe manner. A Runnable only 'executes' its code when it has the boolean true value.
package interleavedexample;
import java.util.concurrent.Exchanger;
import java.util.logging.Logger;
/**
*
*/
public class InterleavedRunnable implements Runnable {
private final String name;
private final Exchanger<Boolean> exchanger;
private Boolean state;
public InterleavedRunnable(String name, Exchanger<Boolean> exchanger,
Boolean state) {
this.name = name;
this.exchanger = exchanger;
this.state = state;
}
#Override
public void run() {
try {
while (true) {
if (state) {
Logger.getLogger(getClass().getName()).info(name + " is running");
}
state = exchanger.exchange(state);
}
} catch (InterruptedException ex) {
Logger.getLogger(name).info("Interrupted");
}
}
Setting up the runnables are quite easy:
public static void main(String[] args) {
Exchanger<Boolean> exchanger = new Exchanger<Boolean>();
Thread thread1 = new Thread(new InterleavedRunnable("Thread 1", exchanger, true));
Thread thread2 = new Thread(new InterleavedRunnable("Thread 2", exchanger, false));
thread1.start();
thread2.start();
}
Anytime you can find existing functionality within the Java API (or well known libraries), you should utilize them to the fullest extent. The less lines of code you write the less lines there are to maintain.
The 'OS Sycnro 101' solution is to use two semaphores, one for each thread, and swap over one 'GO' token/unit between them. Start both threads and then give the token to whichever thread you want to go first.
Use wait and notify for this.
public class Thread1 implements Runnable {
#Override
public void run() {
while(true){
synchronized (Main.obj) {
try {
Main.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("1");
synchronized (Main.obj) {
Main.obj.notify();
}
}
}
}
public class Thread2 implements Runnable{
#Override
public void run() {
while(true){
synchronized (Main.obj) {
try {
Main.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("2");
synchronized (Main.obj) {
Main.obj.notify();
}
}
}
}
public class Main {
public volatile static Object obj = new Object();
/**
* #param args
*/
public static void main(String[] args) {
Thread t1 = new Thread(new Thread1());
Thread t2 = new Thread(new Thread2());
t1.start();
t2.start();
synchronized (obj) {
obj.notifyAll();
}
}
}
Did not get your question correctly. If you want to execute thread B only after thread A execution is over, then there is no point of multi-threading at all. You can simply put the thread B contents in thread A run() method.
Still if it is very much required then you can try using wait() and notify() methods on two objects . Something like this.
Class ClassA implements runnable{
Message messageA;
Message messageB;
public ClassA(Message messageA,,Message messageB){
this.messageA = messageA;
this.messageB = messageB;
}
public void run(){
for(;loop contition;){
//code here
messageB.notify();
messageA.wait();
}
}
}
Class ClassB implements runnable{
Message messageA;
Message messageB;
public ClassB(Message messageA,Message messageB){
this.messageA = messageA;
this.messageB = messageB;
}
public void run(){
for(;loop condition;){
messageB.wait();
//code here
messageA.notify();
}
}
}
now create two objects in main messageA and messageB and pass both of them in the constructor of each thread.