Notify exception java.lang.IllegalMonitorStateException Locks - java

I was trying the wait and notify scenario, getting --> Exception in thread "Thread-1" java.lang.IllegalMonitorStateException when calling notify.
wait method releases the lock, so the threadB can execute the and from threadB i'm calling lock.notify for threadA.
Could you help me on this?
class SynchronizedCodee {
int a = 5;
Lock lock = new ReentrantLock();
public void threadA()
{
lock.lock();
try {
lock.wait();
System.out.println("A = "+a);
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
finally
{
lock.unlock();
}
}
public void threadB()
{
if(lock.tryLock())
{
this.a = 11;
System.out.println("B = "+a);
lock.notify(); // getting erro over here
}
else
{
System.out.println("didn't managed to get a lock");
}
}
}
class ThreadA extends Thread{
SynchronizedCodee s;
public ThreadA(SynchronizedCodee s) {
this.s = s;
}
public void run()
{
s.threadA();
}
}
class ThreadB extends Thread{
SynchronizedCodee s;
public ThreadB(SynchronizedCodee s) {
this.s = s;
}
public void run()
{
s.threadB();
}
}
public class SynchronizedCode{
public static void main(String ag[]) throws InterruptedException
{
SynchronizedCodee s = new SynchronizedCodee();
ThreadA t1 = new ThreadA(s);
ThreadB t2 = new ThreadB(s);
t1.start();
Thread.sleep(100);
t2.start();
}
}

You are calling wait and notify on explicit lock objects and that is not legal. If you are using explicit lock objects, you have to use Condition object associated with it. Then you should call condition.await and condition.signalAll methods instead of wait and notify. Here's the idiom for using explicit locks in your particular scenario.
final Condition setA = lock.newCondition();
public void threadA() {
lock.lock();
try {
while (a == 5)
setA.await();
System.out.println("A = " + a);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
public void threadB() {
lock.lock();
try {
this.a = 11;
System.out.println("B = " + a);
setA.signalAll();
} finally {
lock.unlock();
}
}
And this program produces the following output:
B = 11
A = 11

Related

Trying to create a deadlock between two threads

For creating a deadlock in between two threads by accessing print method into Threads. I have used cyclic Barrier so that both of the thread starts at same time. If I am correct my print method is not taking time, for that reason it is getting shared by the two threads and not causing a Deadlock.
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class TWOTHREADDEADLOCLK {
static int b =0;
synchronized static void print()
{
System.out.println(Thread.currentThread().getName() + " " + b);
}
synchronized static int getb()
{
print();
return b;
}
synchronized static void updateb()
{
print();
b=b+10;
}
public static void main(String[] args) {
final CyclicBarrier bar = new CyclicBarrier(2);
Thread thread1 = new Thread(new Runnable(){
#Override
public void run()
{
try {
bar.await();
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch ( BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
print();
}
});
Thread thread2 = new Thread(new Runnable(){
#Override
public void run()
{try {
bar.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
getb();
}
});
thread1.start();
thread2.start();
}
}
You can't create a deadlock with a single barrier. The idea behind a deadlock is to have (at least) two threads, each one holding a different lock and attempting to take a lock on the other one. E.g., consider this simple example:
public class TwoLockRunnable implements Runnable {
private Lock lockInConstructor;
private Lock lockInRuntime;
public TwoLockThread(Lock lockInConstructor, Lock lockInRuntime) {
this.lockInConstructor = lockInConstructor;
this.lockInRuntime = lockInRuntime;
this.lockInConstructor.lock();
}
#Override
public void run() {
lockInRuntime.lock();
System.out.println("After the lock in run()");
}
public static void main(String[] args) {
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
TwoLockRunnable runnable1 = new TwoLockThread(lock1, lock2);
TwoLockRunnable runnable2 = new TwoLockThread(lock2, lock1);
new Thread(runnable1).start();
new Thread(runnable2).start();
}
}
The first thread locks lock1 in its constructor and the second locks lock2 in its constructor. The first thread then tries to lock lock2 when its run - but it can't since lock is held by the other thread. Similarly, the second thread attempts to lock lock1 when its run, and fails for the same reason. Thus, you get a deadlock, and the message "After the lock in run()" is never printed.
like Mureinik's, this is the 'synchronized' demo:
public class DeadLockAATest {
static void methodA(DeadLockAATest d1, DeadLockAATest d2) {
synchronized (d1) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (d2) {
System.out.println("\t\t\tmethodA:" + Thread.currentThread().getName());
}
}
}
public static void main(String[] args) {
DeadLockAATest d1 = new DeadLockAATest(), d2 = new DeadLockAATest();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("t1-start:" + Thread.currentThread().getName());
methodA(d1, d2);
System.out.println("t1-end:" + Thread.currentThread().getName());
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("t2-start:" + Thread.currentThread().getName());
methodA(d2, d1);
System.out.println("t2-end:" + Thread.currentThread().getName());
}
});
t1.start();
t2.start();
System.out.println("deadlock...");
}
}
the deadlock output(just one contion, maybe t2 starts first):
t1-start:Thread-0
deadlock...
t2-start:Thread-1
you can replace
methodA(d2, d1);
to
methodA(d1, d2);
and this will output:
t1-start:Thread-0
t2-start:Thread-1
deadlock...
methodA:Thread-0
t1-end:Thread-0
methodA:Thread-1
t2-end:Thread-1
and this is not deadlock, hope to help you.

Inter thread Communication-Java

I am new to java thread. I am unable to give the lock back to the thread from the main thread in the following code. I am getting the undesired output because i am unable to unlock the thread. I want thread to increment the value using thread (goes to wait state after that) and after printing the value, release the lock to print the next incremented value.
class Foo implements Runnable
{
public volatile int value=0,i=0;
Thread t=new Thread();
public void method(Thread t)
{
this.t = t;
}
#Override
public synchronized void run()
{
while(i<3)
{
value++;//receive and process ACK
i++;
try
{
System.out.println("im thread here");
wait();
System.out.println("passed wait");
}
catch(InterruptedException ex){
}
System.out.println("im notified");
}//while
//}//sync
}//run method
public int getValue()
{
try
{
Thread.sleep(1000);
}
catch (Exception e) {
System.out.println(e);
}
return value;
}
}//class foo
public class ThreadTest
{
public static int value1,times=0;
public static void main(String[] args)
{
Foo foo=new Foo();
Thread t=new Thread(foo);
foo.method(t);
t.start();
while(times<3)
{
synchronized(t)
{
value1=foo.getValue();
times++;
System.out.println(value1);
System.out.println(t.getState());
try
{
t.notify();
System.out.println("Notify is reached");
}
catch(IllegalMonitorStateException ex)
{
System.out.println("Thread is blocked");
}
}//sync
}//while
}//main
}//mclasss
Are you trying to do something like this? If you really must use wait/notify & want to use Runnable.
I added a wait block, otherwise the main thread may finish before the background thread increments the value.
class Foo implements Runnable {
public volatile int value = 0, i = 0;
private Thread backgroundThread;
public void setThread(Thread thread) {
this.backgroundThread = thread;
}
#Override
public void run() {
synchronized (backgroundThread) {
while (i < 2) {
value++;
i++;
backgroundThread.notify();
try {
System.out.println("background thread wait start");
backgroundThread.wait();
System.out.println("background thread notified");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
public int getValue() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}
public class ThreadTest {
public static int value1, times = 0;
public static void main(String[] args) {
Foo foo = new Foo();
final Thread thread = new Thread(foo);
foo.setThread(thread);
thread.start();
while (times < 3) {
synchronized (thread) {
value1 = foo.getValue();
times++;
System.out.println(value1);
System.out.println(thread.getState());
thread.notify();
try {
thread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Or you can extend thread:
class BackgroundThread extends Thread {
public volatile int value = 0, i = 0;
#Override
public synchronized void run() {
while (i < 2) {
value++;
i++;
notify();
try {
System.out.println("background thread wait start");
wait();
System.out.println("background thread notified");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public int getValue() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}
public class ThreadTest {
public static int value1, times = 0;
public static void main(String[] args) {
BackgroundThread backgroundThread = new BackgroundThread();
backgroundThread.start();
while (times < 3) {
synchronized (backgroundThread) {
value1 = backgroundThread.getValue();
times++;
System.out.println(value1);
System.out.println(backgroundThread.getState());
backgroundThread.notify();
try {
backgroundThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
It is very unclear what you really want to do but we will assume here that you want to run a thread in the background which should run only when its spawner (let's say the main thread) allows it to.
The JDK has several tools for this already, no need to rely on the low level wait() and notify{,All}() methods.
One example of such a primitive is a CountDownLatch. It is a one-use entity which allows you to specify the times a given set of threads should countDown() it before any threads .await()ing for them can trigger.
In combination with the multithread handling classes which appeared as far back as Java 1.5, this means you could do something like this:
// Implementation of a Runnable waiting for the counter to trigger
public final class MyWaitingClass
implements Runnable
{
private final CountDownLatch latch;
public MyWaitingClass(final CountDownLatch latch)
{
this.latch = latch;
}
#Override
public void run()
{
try {
latch.await();
// do whatever is necessary
} catch (InterruptedException e) {
// Argh; interrupted before the latch was released
Thread.currentThread().interrupt();
}
}
}
// In the main class:
final ExecutorService executor = Executors.newSingleThreadPool();
final CountDownLatch latch = new CountDownLatch(1);
final Runnable runnable = new MyWaitingClass(latch);
executor.submit(runnable);
// do whatever is needed; then:
latch.countDown();

IllegalMonitorStateException on notify() when synchronized on an Integer

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.

Printing "Hello" and "world" multiple times using two threads in java

Assume that one thread prints "Hello" and another prints "World". I have done it successfully for one time, as follows:
package threading;
public class InterThread {
public static void main(String[] args) {
MyThread mt=new MyThread();
mt.start();
synchronized(mt){
System.out.println("Hello");
try {
mt.wait();
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread extends Thread{
public void run(){
synchronized(this){
System.out.println("World!");
notify();
}
}
}
How do I do it for multiple time printing, say for 5 times? I tried putting for loop around the synchronized block, but of no use.
Here being two interdependent threads, we need two synchronizing objects. they could be one of many things. one integer, another object; one Boolean another object; both object; both semaphores and so on. the synchronization technique could be either Monitor or Semaphore any way you like, but they have to be two.
I have modified your code to use semaphore instead of Monitor. The Semaphore works more transparently. You can see the acquire and release happening. Monitors are even higher constructs. Hence Synchronized works under the hood.
If you are comfortable with the following code, then you can convert it to use Monitors instead.
import java.util.concurrent.Semaphore;
public class MainClass {
static Semaphore hello = new Semaphore(1);
static Semaphore world = new Semaphore(0);
public static void main(String[] args) throws InterruptedException {
MyThread mt=new MyThread();
mt.hello = hello;
mt.world = world;
mt.start();
for (int i=0; i<5; i++) {
hello.acquire(); //wait for it
System.out.println("Hello");
world.release(); //go say world
}
}
}
class MyThread extends Thread{
Semaphore hello, world;
public void run(){
try {
for(int i = 0; i<5; i++) {
world.acquire(); // wait-for it
System.out.println(" World!");
hello.release(); // go say hello
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadSeq {
Object hello = new Object();
Object world = new Object();
public static void main(String[] args) throws InterruptedException {
for(int i=0; i<6;i++){
Runnable helloTask = new Runnable(){
#Override
public void run(){
new ThreadSeq().printHello();
}
};
Runnable worldTask = new Runnable(){
#Override
public void run(){
new ThreadSeq().printWorld();
}
};
Thread t1 = new Thread(helloTask);
Thread t2 = new Thread(worldTask);
t1.start();
t1.join();
t2.start();
t2.join();
}
}
public void printHello(){
synchronized (hello) {
System.out.println("Hello");
}
}
public void printWorld(){
synchronized (world) {
System.out.println("World");
}
}
}
The goal here is to synchronize threads so that when one is done it notify the other. If I have to make it, it would be 2 threads executing the same code with different data. Each thread has its own data ("Hello" and true to T1, "World" and false to t2), and share a variable turn plus a separate lock object.
while(/* I need to play*/){
synchronized(lock){
if(turn == myturn){
System.out.println(mymessage);
turn = !turn; //switch turns
lock.signal();
}
else{
lock.wait();
}
}
}
Before you start trying to get it to work five times you need to make sure it works once!
Your code is not guaranteed to always print Hello World! - the main thread could be interrupted before taking the lock of mt (note that locking on thread objects is generally not a good idea).
MyThread mt=new MyThread();
mt.start();
\\ interrupted here
synchronized(mt){
...
One approach, that will generalise to doing this many times, is to use an atomic boolean
import java.util.concurrent.atomic.AtomicBoolean;
public class InterThread {
public static void main(String[] args) {
int sayThisManyTimes = 5;
AtomicBoolean saidHello = new AtomicBoolean(false);
MyThread mt=new MyThread(sayThisManyTimes,saidHello);
mt.start();
for(int i=0;i<sayThisManyTimes;i++){
while(saidHello.get()){} // spin doing nothing!
System.out.println("Hello ");
saidHello.set(true);
}
}
}
class MyThread extends Thread{
private final int sayThisManyTimes;
private final AtomicBoolean saidHello;
public MyThread(int say, AtomicBoolean said){
super("MyThread");
sayThisManyTimes = say;
saidHello = said;
}
public void run(){
for(int i=0;i<sayThisManyTimes;i++){
while(!saidHello.get()){} // spin doing nothing!
System.out.println("World!");
saidHello.set(false);
}
}
}
This is in C:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t hello_lock, world_lock;
void printhello()
{
while(1) {
pthread_mutex_lock(&hello_lock);
printf("Hello ");
pthread_mutex_unlock(&world_lock);
}
}
void printworld()
{
while(1) {
pthread_mutex_lock(&world_lock);
printf("World ");
pthread_mutex_unlock(&hello_lock);
}
}
int main()
{
pthread_t helloThread, worldThread;
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_join(helloThread);
pthread_join(worldThread);
return 0;
}
There are two thread and both has its own data ("Hello" and true to ht, "World" and false to wt), and share a variable objturn.
public class HelloWorldBy2Thread {
public static void main(String[] args) {
PrintHelloWorld hw = new PrintHelloWorld();
HelloThread ht = new HelloThread(hw);
WorldThread wt = new WorldThread(hw);
ht.start();
wt.start();
}
}
public class HelloThread extends Thread {
private PrintHelloWorld phw;
private String hello;
public HelloThread(PrintHelloWorld hw) {
phw = hw;
hello = "Hello";
}
#Override
public void run(){
for(int i=0;i<10;i++)
phw.print(hello,true);
}
}
public class WorldThread extends Thread {
private PrintHelloWorld phw;
private String world;
public WorldThread(PrintHelloWorld hw) {
phw = hw;
world = "World";
}
#Override
public void run(){
for(int i=0;i<10;i++)
phw.print(world,false);
}
}
public class PrintHelloWorld {
private boolean objturn=true;
public synchronized void print(String str, boolean thturn){
while(objturn != thturn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(str+" ");
objturn = ! thturn;
notify();
}
}
In simple way we can do this using wait() and notify() without creating any extra object.
public class MainHelloWorldThread {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
Thread t1 = new Thread(() -> {
try {
helloWorld.printHello();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
helloWorld.printWorld();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// printHello() will be called first
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
class HelloWorld {
public void printHello() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 500ms
Thread.sleep(500);
System.out.print("Hello ");
wait();
// This thread will wait to call notify() from printWorld()
notify();
// This notify() will release lock on printWorld() thread
}
}
}
public void printWorld() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 100ms
Thread.sleep(100);
System.out.println("World");
notify();
// This notify() will release lock on printHello() thread
wait();
// This thread will wait to call notify() from printHello()
}
}
}
}

java thread interleaving

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.

Categories