How to write a simple fair lock? - java

How to write a simple fair lock analog to new ReentrantLock(true)?
public class Main1 {
public static void main(String[] args) {
// Lock lock = new ReentrantLock(true);
CustomLock lock = new CustomLock();
new Thread(new Producer(lock)).start();
new Thread(new Consumer(lock)).start();
}
}
class Producer implements Runnable {
private Lock lock;
private CustomLock customLock;
public Producer(Lock lock) {
this.lock = lock;
}
public Producer(CustomLock lock) {
this.customLock = lock;
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// lock.lock();
customLock.lock();
System.out.println("Producer before");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer after");
// lock.unlock();
customLock.unlock();
}
}
}
class Consumer implements Runnable {
private Lock lock;
private CustomLock customLock;
public Consumer(Lock lock) {
this.lock = lock;
}
public Consumer(CustomLock lock) {
this.customLock = lock;
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// lock.lock();
customLock.lock();
System.out.println("Consumer before");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Consumer after");
// lock.unlock();
customLock.unlock();
}
}
}
class CustomLock{
private boolean isLocked;
public synchronized void lock(){
while (isLocked) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isLocked = true;
}
public synchronized void unlock(){
if(isLocked){
isLocked = false;
notify();
}
}
}
Custom not fair Lock (I am not sure that it's correct)
class CustomLock{
private boolean isLocked;
public synchronized void lock(){
while (isLocked) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isLocked = true;
}
public synchronized void unlock(){
if(isLocked){
isLocked = false;
notify();
}
}
}

If you want a fair lock you need to use a list and notify threads following the list order.

Related

How to run while loops in different threads? [duplicate]

I got asked this question recently in an interview.
Write a program with two threads (A and B), where A prints 1 , B prints 2 and so on until 50 is reached.
How do we go about doing that ?
The essence of the assignment is to demonstrate how a thread can signal another one. Most common way is to use blocking queues, but here a signal does not carry any information, so a Semaphore is sufficient.
Create thread class which is parameterized with 2 Semaphores: input and output:
class ThreadPrinter implements Runnable {
int counter;
Semaphore ins, outs;
ThreadPrinter(int counter, Semaphore ins, Semaphore outs) {
this.counter = counter;
this.ins = ins;
this.outs = outs;
}
#Override
public void run() {
for (int i = 0; i < 25; i++) {
ins.aquire(); // wait for permission to run
System.out.println("" + counter);
outs.release(); // allow another thread to run
counter += 2;
}
}
Create 2 Semaphores and pass them to 2 threads:
Semaphore a = new Semaphore(1); // first thread is allowed to run immediately
Semaphore b = new Semaphore(0); // second thread has to wait
ThreadPrinter tp1 = new ThreadPrinter(1, a, b);
ThreadPrinter tp2 = new ThreadPrinter(2, b, a);
Note semaphores a and b are passed in different order.
public class Test {
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 25; i++) {
synchronized (CommonUtil.mLock) {
incrementCount();
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 25; i++) {
synchronized (CommonUtil.mLock) {
incrementCount();
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
t1.start();
Thread.sleep(400);
t2.start();
t1.join();
t2.join();
}
private static void incrementCount() {
count++;
System.out.println("Count: " + count + " icnremented by: " + Thread.currentThread().getName());
}
}
class CommonUtil {
static final Object mLock = new Object();
}
I encountered the same problem and was expected to use only basics so I choose wait notify on shared object between threads
public class Message implements Runnable {
private static final int N = 10;
private Thread thread;
private static Object object = new Object();
public Message(String name){
thread = new Thread(this, name);
thread.start();
}
public void run(){
for(int i=0; i<N; i++){
synchronized (object) {
System.out.println(i + "--" + thread.getName());
object.notify();
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
In main method :
Message message1 = new Message("Ping");
Message message2 = new Message("Pong");
public class ThreadCounter implements Runnable {
private static int count = 0;
private Thread t;
public ThreadCounter(String tName){
t= new Thread(this, tName);
t.start();
}
#Override
public void run() {
for(int i=1; i<=5; i++){
synchronized (CommonUtil.mLock) {
incrementCount(t.getName());
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void incrementCount(String tName){
System.out.println(tName+": "+(++ThreadCounter.count));
}
public static void main(String[] args) throws InterruptedException {
new ThreadCounter("Thread1");
Thread.sleep(500);
new ThreadCounter("Thread2");
}
}
class CommonUtil{
public static Object mLock = new Object();
}
hi please find answer here...pattern ABABABAB
package com.abhi.ThreadPractice;
public class Test {
public static void main(String[] args) throws InterruptedException {
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
// count++;
System.out.println("A");
try {
lock.wait();
lock.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
lock.notify();
//count++;
System.out.println("B");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
This is another solution:
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
for (int i = 1; i <= 50; i += 2) {
System.out.println("T1=" + i);
t1turn = false;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
for (int i = 2; i <= 50; i += 2) {
if (t1turn)
try {
lock.wait();
} catch (InterruptedException e) {
}
System.out.println("T2=" + i);
t1turn = true;
lock.notify();
}
}
}
});
t1.start();
t2.start();
May be this is still relevant:
public class MyRunnable implements Runnable {
public static int counter = 0;
public static int turn = 0;
public static Object lock = new Object();
#Override
public void run() {
while (counter < 50) {
synchronized (lock) {
if (turn == 0) {
System.out.println(counter + " from thread "
+ Thread.currentThread().getName());
turn = 1;
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
} else {
turn = 0;
lock.notify();
}
}
}
}
}
and then the main function
public static void main(String[] args) {
Thread threadA = new Thread(new MyRunnable());
Thread threadB = new Thread(new MyRunnable ());
threadA.start();
threadB.start();
}
public class PingPong extends Thread {
static StringBuilder object = new StringBuilder("");
public static void main(String[] args) throws InterruptedException {
Thread t1 = new PingPong();
Thread t2 = new PingPong();
t1.setName("\nping");
t2.setName(" pong");
t1.start();
t2.start();
}
#Override
public void run() {
working();
}
void working() {
while (true) {
synchronized (object) {
try {
System.out.print(Thread.currentThread().getName());
object.notify();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
This was the simplest solution, I was able to think of. It uses a synchronized method and uses the notify() and the wait() to alternatively print the numbers. Hope it helps. :)
public class program implements Runnable
{
static int count =1;
private static final int MAX_COUNT = 50;
public synchronized void print ()
{
System.out.println(Thread.currentThread().getName() + " is printing " + count);
count++;
notify();
try{
if(count>MAX_COUNT)
return;
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void run()
{
for(int i=0;i<MAX_COUNT/2;i++)
{
print();
}
}
public static void main(String[] args) {
program x= new program();
Thread t0= new Thread(x);
Thread t1= new Thread(x);
t0.start();
try
{
Thread.sleep(1);
} catch (InterruptedException e){
e.printStackTrace();
}
t1.start();
}
}
//simply use wait and notify and and set a counter and it will do
public class ThreadalternatePrint implements Runnable {
static int counter =0;
#Override
public synchronized void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(counter<51)
{ ++counter;
notify();
System.out.println(Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadalternatePrint obj1 = new ThreadalternatePrint();
Thread Th1 = new Thread(obj1);
Thread Th2 = new Thread(obj1);
Th1.setName("Thread1");
Th2.setName("Thread2");
Th1.start();
Th2.start();
}
}
public class Testing implements Runnable {
private static int counter = 1;
private static final Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Testing(), "1");
t1.start();
Thread t2 = new Thread(new Testing(), "2");
t2.start();
}
#Override
public void run() {
while (counter<=100) {
synchronized (lock) {
if (counter % 2 == 0) {
System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
counter++;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (counter % 2 == 1) {
System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
counter++;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
I have created a pretty basic Solution for it using the Reentrant Lock.
package com.multithreding.trylock;
import java.util.concurrent.locks.ReentrantLock;
public class TryLock extends Thread {
static int intitialCount = 50; //Value till which you want to print
int valueToSubtract = 0; //Value by which difference you want to print the series like 1,2,3
static ReentrantLock alternate = new ReentrantLock();
public TryLock(String name) {
this.setName(name);
}
public void run() {
while (intitialCount > 1) {
if (valueToSubtract > 0) {
alternate.lock();
intitialCount = intitialCount - valueToSubtract;
valueToSubtract = 0;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("value Subtracted " + intitialCount + " by the Thread" + this.getName());
alternate.unlock();
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
valueToSubtract++;
}
}
}
}
package com.multithreding.trylock;
public class AlternatePrint {
public static void main(String[] args) throws InterruptedException{
//You can add as many thread to print then in different number of series
TryLock t1 = new TryLock("Odd One");
TryLock t2 = new TryLock("Even Value");
t1.start();
t2.start();
}
}
This solution is modular as well,
You can add 'n' number of Threads to print the alternate series. i.e Using 3 thread at once
You can also print the series with more than Difference of more than 1. i.e 1,3,5 etc
package thread;
public class Pingpong extends Thread {
static StringBuilder object = new StringBuilder("");
static int i=1;
#Override
public void run() {
working();
}
void working() {
while (i<=10) {
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName() +" "+ i);
i++;
object.notify();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Pingpong();
Thread t2 = new Pingpong();
t1.setName("Thread1");
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Thread1 1
Thread2 2
Thread1 3
Thread2 4
Thread1 5
Thread2 6
Thread1 7
Thread2 8
Thread1 9
Thread2 10
This answer is generic i.e. not only to print numbers alternately from 2 threads but to execute 2 threads alternately.
The above approaches are commendable but this one doesn't need any lock but instead it uses an AtomicInteger variable alongwith 2 AtomicBooleans to indicate when one thread has finished executing so that the other can finish executing the rest of its remaining execution.
This will work in all 3 cases:
When number of executions of both threads are same.
When first thread finishes before second thread and second thread has more number of executions than first thread.
When second thread finishes before first thread and first thread has more number of executions than second thread.
public class TestAlternateExecutionOfTwoThreads
{
private static final AtomicInteger count = new AtomicInteger(0);
private static final AtomicBoolean firstIsDone = new AtomicBoolean(false);
private static final AtomicBoolean secondIsDone = new AtomicBoolean(false);
// change the below values to change the number of iterations each thread should
// run. In this example, the initial value are hard-coded but you can change
// them as well.
private static final int finalOfFirstThread = 10;
private static final int finalOfSecondThread = 109;
public static void main(String[] args)
{
Runnable r1 = () -> {
int i = 1;
for(; i <= finalOfFirstThread; )
{
while(count.get() == 0)
{
System.out.println(i);
count.incrementAndGet();
i++;
}
if(count.get() == 1 && secondIsDone.get() && i != (finalOfFirstThread + 1))
{
System.out.println(i);
i++;
}
}
firstIsDone.set(true);
};
Runnable r2 = () -> {
int j = 100;
for (; j <= finalOfSecondThread; )
{
while(count.get() == 1)
{
System.out.println(j);
count.decrementAndGet();
j++;
}
if(count.get() == 0 && firstIsDone.get() && j != (finalOfSecondThread + 1))
{
System.out.println(j);
j++;
}
}
secondIsDone.set(true);
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
I guess this might help.
Although it is not standard but i hope it provides a simpler approach.
public class ThreadDemo
{
public static void main (String [] args)
{
PrintDemo pd=new PrintDemo();
MyThread1 mt1 = new MyThread1 ("T1",pd);
MyThread2 mt2 = new MyThread2 ("T2",pd);
mt1.start ();
mt2.start();
}
}
class PrintDemo {
private boolean oddFlag=true;
public synchronized void printOdd(int i,String tName){
if(oddFlag==false){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("\nThread "+tName+" count:"+i);
oddFlag=false;
notify();
}
}
public synchronized void printEven(int i,String tName){
if(oddFlag==true){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("\nThread "+tName+" count:"+i);
oddFlag=true;
notify();
}
}
}
class MyThread1 extends Thread
{
private PrintDemo pd;
private String name;
MyThread1(String threadName,PrintDemo pd){
this.name=threadName;
this.pd=pd;
}
public void run ()
{
for(int i=1;i<=50;i+=2){
pd.printOdd(i,name);
}
}
}
class MyThread2 extends Thread
{
private PrintDemo pd;
private String name;
MyThread2(String threadName,PrintDemo pd){
this.name=threadName;
this.pd=pd;
}
public void run ()
{
for(int i=2;i<=50;i+=2){
pd.printEven(i,name);
}
}
}

Run a method on specific thread given the thread id

If i know a specific thread id. How to do the following?
Thread.getThreadById(id).continueWork();
Is it possible?
public class Test implements Runnable {
public void run() {
while(true){
pause();
doSomework();
}
}
private void doSomework() {
System.out.println("do some work");
}
public synchronized void pause() {
if (Tester.waitCondition == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void continueWork() {
notify();
}
}
public class Tester {
public static boolean waitCondition = true;
public static void main(String[] args) {
Thread nThread = new Thread(new Test());
nThread.start();
waitCondition = false;
Thread nThread1 = new Thread(new Test());
nThread1.start();
Thread nThread2 = new Thread(new Test());
nThread2.start();
Thread nThread3 = new Thread(new Test());
nThread3.start();
Long id = nThread.getId();
Thread.getThreadById(id).continueWork();
}
}
You need block the thread with a lock , then call the lock's notify method to set blocked thread runnable .
If more than one thread to be continued , you will need Condition .
Like blow:
final Lock lock = new ReentrantLock();
final Condition condition1 = lock.newCondition();
final Condition condition2 = lock.newCondition();
Thread t = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition1.await();
System.out.println("end cdt1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
t.start();
Thread t1 = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition2.await();
System.out.println("end cdt2");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
t1.start();
Thread.sleep(1000);
Thread tt = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition1.signal();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
tt.start();
Thread.sleep(2000);
Thread tt1 = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition2.signal();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
tt1.start();
Elaborating:
public class Tester {
// Apologies, I'm too lazy to create two separate files
static public class Test implements Runnable {
private void doSomework() {
System.out.print(
"do some work on Thread: "
+Thread.currentThread().getId()
);
try {
Thread.sleep(500); // just to simulate a load
}
catch(InterruptedException e) {
// ignore
}
}
public void run() {
do {
boolean shouldIWait=true;
synchronized(Tester.lockingObj) {
Boolean flag=Tester.waitConditions.get(Thread.currentThread().getId());
if(null!=flag) {
shouldIWait=flag.booleanValue();
} // if null, the tester started me before creating my flag. I'll wait
if(shouldIWait) {
// I need to wait for someone to wake me
try {
Tester.lockingObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
// well, I'm interrupted, so I'll do no more work.
break;
}
}
}
if(false==shouldIWait) {
// waiting no more
this.doSomework();
}
} while(true);
}
}
public static Object lockingObj=new Object();
public static TreeMap<Long, Boolean> waitConditions=
new TreeMap<Long, Boolean>();
public static void main(String[] args) {
Thread nThread = new Thread(new Test());
Thread nThread1 = new Thread(new Test());
Thread nThread2 = new Thread(new Test());
Thread nThread3 = new Thread(new Test());
// when starting, all threads will be waiting
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
nThread2.start();
nThread1.start();
nThread.start();
nThread3.start();
Long id = nThread.getId();
synchronized (lockingObj) { // when notified, all thread should wakeup
waitConditions.put(id, false); // but only nThread will be allowed to doSomeWork
lockingObj.notifyAll(); // wake up all the threads.
// Those not allowed, will go into
// back waiting
}
try {
// just to have the main thread still running for a while
Thread.sleep(3000);
} catch (InterruptedException e) {
}
// maybe we want to switch of nThread and start another?
synchronized (lockingObj) {
waitConditions.put(id, true);
waitConditions.put(nThread1.getId(), false);
lockingObj.notifyAll();
}
try {
// just to have the main thread still running for a while
Thread.sleep(3000);
} catch (InterruptedException e) {
}
}
}

How to make two thread wait for each other outcome?

Here is my example code.
class A implements Runnable{
//stuff
Thread thr = new Thread(this);
boolean flag;
public void run()
{
while(true){
if(condition)flag = true;
}
}
}
class B implements Runnable{
//stuff
A a = new A();
Thread thr = new Thread(this);
public void run()
{
while(true){
//i ll do some thing here
if(a.flag == true)System.out.println("Kaboom");
}
}
public static void main(String[] args)
{
B b = new B();
}
}
So the thing is i start b before a and i want b to wait until a.flag == true to fire "Kaboom" and a.thr have to wait when b doing its work in run() method. I tried this but it doesnt work
class A implements Runnable{
//stuff
Thread thr = new Thread(this);
boolean flag;
public void run()
{
while(true){
if(condition)flag = true;
synchronized(B.class){
this.flag=true;
B.class.notifyAll();
}
}
}
}
class B implements Runnable{
//stuff
A a = new A();
Thread thr = new Thread(this);
public void run()
{
while(true){
synchronized(this){
while(a.flag!=true)
{
this.wait();
}}
}
}
public static void main(String[] args)
{
B b = new B();
}}
There must be a problem in my synchronized block but i dont know what.
This probably a stupid question but i'm just a beginner in JAVA and i dont really get those Thread stuff and how it work. Plz help me
I like your original approach of using wait / notifyAll to make the Thread doesn't use the CPU until the condition is met for it to resume running. Here's a solution that keeps this approach.
A few notes:
1 - Be careful when synchronizing on a class object. Unless you really want to synchronize the whole class, create an Object and use it as a lock.
2 - Use the volatile keyword to ensure that Java doesn't create a thread local version of the variable and that changes to it's value are instantly reflected to other threads.
public class Threads {
private final Object lock = new Object();
private volatile boolean flag;
class RunnableA implements Runnable {
private volatile boolean condition = false;
#Override
public void run() {
while (true) {
if (condition) {
if (!flag) {
synchronized (lock) {
System.out.println("Setting Flag to True");
flag = true;
lock.notifyAll();
}
}
} else {
System.out.println("Condition is False");
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
}
}
}
}
class RunnableB implements Runnable {
#Override
public void run() {
while (true) {
while (flag == false) {
synchronized (lock) {
if (flag == false) {
try {
lock.wait();
} catch (InterruptedException ex) {
}
}
}
}
System.out.println("Kaboom");
}
}
}
public void run() {
RunnableA runnableA = new RunnableA();
RunnableB runnableB = new RunnableB();
Thread t1 = new Thread(runnableA);
Thread t2 = new Thread(runnableB);
t1.start();
t2.start();
try {
Thread.sleep(5000L);
} catch (InterruptedException ex) {
}
runnableA.condition = true;
}
public static void main(String[] args) {
new Threads().run();
}
}
You created a Runnable but did not start it in a thread.
Proper one:
import java.lang.*;
import java.util.concurrent.atomic.*;
class A implements Runnable {
AtomicBoolean flag;
AtomicBoolean condition;
A() {
flag = new AtomicBoolean();
condition = new AtomicBoolean();
}
public void run(){
while (true) {
System.out.println("A");
if (condition.get()) {
flag.set(true);
return ;
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B implements Runnable {
A a;
B() {
a = new A();
}
public void run() {
while (true) {
System.out.println("B");
if (a.flag.get()) {
System.out.println("Kaboom");
return ;
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
B b = new B();
new Thread(b).start();
new Thread(b.a).start();
b.a.condition.set(true);
}
}

Odd even sequence java 2 thread

I am trying to write a program with two Java threads. One shall print odd and the other shall print even numbers. The output should be in sequence. My code is not working properly. Please correct it and tell me what was the error.
public class App {
public static void main(String[] args) {
ThrdO to=new ThrdO();
Thread t1=new Thread(to);
ThredE te=new ThredE();
Thread t2=new Thread(te);
t1.start();
t2.start();
}
}
public class ThrdO implements Runnable{
PrintCl pcl =new PrintCl();
#Override
public void run() {
for(int i=0;i<10;i+=2)
pcl.Even(i);
}
}
public class ThredE implements Runnable {
PrintCl pcl =new PrintCl();
#Override
public void run() {
for(int i=1;i<10;i+=2)
try {
pcl.odd(i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class PrintCl {
public void Even(int n) {
synchronized (this) {
System.out.println(n);
this.notifyAll();
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void odd(int n) throws InterruptedException {
synchronized (this) {
System.out.println(n);
this.notifyAll();
this.wait();
}
}
}
getting output
0 ,1
This is a much cleaner way of achieving what you want, without ugly sleeps in the code, not to mention that it will run faster than code with a sleep in it, for obvious reasons.
public class App {
public static void main(String[] args) {
PrintCl pcl = new PrintCl();
Thread t1 = new Thread(new ThrdEven(pcl));
Thread t2 = new Thread(new ThrdOdd(pcl));
t1.start();
t2.start();
}
}
public class ThrdEven implements Runnable {
private PrintCl pcl = null;
public ThrdEven(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for (int i = 0; i < 10; i += 2) {
pcl.Even(i);
}
}
}
public class ThrdOdd implements Runnable {
private PrintCl pcl = null;
public ThrdOdd(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for (int i = 1; i < 10; i += 2) {
pcl.odd(i);
}
}
}
public class PrintCl {
private final Object _lock = new Object();
private boolean isEvenAllowed = true;
public void Even(int n) {
synchronized (this._lock) {
while (!this.isEvenAllowed) {
try {
this._lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
System.out.println(n);
this.isEvenAllowed = false;
this._lock.notifyAll();
}
}
public void odd(int n) {
synchronized (this._lock) {
while (this.isEvenAllowed) {
try {
this._lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
System.out.println(n);
this.isEvenAllowed = true;
this._lock.notifyAll();
}
}
}
Please try following changes in your code:
public class App {
public static void main(String[] args) throws InterruptedException {
PrintCl pcl =new PrintCl();
ThrdO to=new ThrdO();
to.setPcl(pcl);
Thread t1=new Thread(to);
ThredE te=new ThredE();
te.setPcl(pcl);
Thread t2=new Thread(te);
t1.start();
Thread.sleep(1000);
t2.start();
}
}
And for Thrd0:
public class ThrdO implements Runnable {
PrintCl pcl =null;
#Override
public void run() {
for(int i=0;i<10;i+=2)
pcl.Even(i);
}
public PrintCl getPcl() {
return pcl;
}
public void setPcl(PrintCl pcl) {
this.pcl = pcl;
}
}
ThredE:
public class ThredE implements Runnable {
PrintCl pcl =null;
#Override
public void run() {
for(int i=1;i<10;i+=2)
try {
pcl.odd(i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public PrintCl getPcl() {
return pcl;
}
public void setPcl(PrintCl pcl) {
this.pcl = pcl;
}
}
Your code has two basic problems
Every thread have its own printing resource . Hence once printing their first number they are waiting for notification endlessly.
Once you will fix this issue , Another issue is your one thread will be finished but second thread would still be waiting for its notification and it will never die.
I have fixed both issues in below code
public class Test {
public static void main(String[] args) throws InterruptedException {
PrintCl pcl =new PrintCl();
ThrdO to=new ThrdO(pcl);
Thread t1=new Thread(to);
ThredE te=new ThredE(pcl);
Thread t2=new Thread(te);
t1.start();
Thread.sleep(1000);// just to ensure that T1 should start first
t2.start();
}
}
class ThrdO implements Runnable{
private PrintCl pcl;
public ThrdO(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for(int i=0;i<10;i+=2) {
try {
pcl.Even(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (pcl){
System.out.println("Releasing lock on pcl");
pcl.notify();
}
System.out.println("ThrdO has finished its working");
}
}
class ThredE implements Runnable {
PrintCl pcl ;
public ThredE(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for (int i = 1; i < 10; i += 2) {
try {
pcl.odd(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (pcl){
System.out.println("Releasing lock on pcl ");
pcl.notify();
}
System.out.println("ThredE has finished its working");
}
}
class PrintCl {
public void Even(int n) throws InterruptedException {
synchronized (this) {
System.out.println("even - "+n);
this.notifyAll();
this.wait();
}
}
public void odd(int n) throws InterruptedException {
synchronized (this) {
System.out.println("odd "+n);
this.notifyAll();
this.wait();
}
}
}

Java method NotifyAll() isn't working?

I'm a little stumped. Below is pretty much a copy and paste from A simple scenario using wait() and notify() in java.
To my understanding, this Java program below should be printing yumyum.. to the screen but it isn't. I am in Eclipse for Mac OS X. Any ideas what I'm doing wrong ?
public class Main {
public static void main(String[] args) {
MyHouse house = new MyHouse();
house.eatPizza();
house.pizzaGuy();
}
}
class MyHouse extends Thread {
private boolean pizzaArrived = false;
public void eatPizza() {
synchronized (this) {
while (!pizzaArrived) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
System.out.println("yumyum..");
}
public void pizzaGuy() {
synchronized (this) {
this.pizzaArrived = true;
notifyAll();
}
}
}
You have one thread. The single thread will wait indefinitely (it needs to be notified by another thread). Try creating another thread in which one will eatPizza() and one will pizzaGuy
Try this...
public class Main {
public static void main(String[] args) {
MyHouse house = new MyHouse();
house.start();
// house.eatPizza();
// Halt main thread momentarily to delay Mr Pizza Guy
try { Thread.sleep(3000); } catch(Exception e) {}
house.pizzaGuy();
}
}
class MyHouse extends Thread {
private boolean pizzaArrived = false;
private Object lock = new Object();
#Override
public void run() {
eatPizza();
}
public void eatPizza() {
synchronized (lock) {
while (!pizzaArrived) {
try {
System.out.println("Waiting for Pizza guy");
lock.wait();
} catch (InterruptedException e) {
}
}
System.out.println("Pizza arrived!!!");
}
System.out.println("yumyum..");
}
public void pizzaGuy() {
synchronized (lock) {
this.pizzaArrived = true;
lock.notifyAll();
}
}
}
Try below code working fine.
public class WaitNotify {
private static int i = 1;
private static boolean flag = false;
static Object obj = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable(){
#Override
public void run() {
while(i<10){
synchronized (obj) {
try {
if(i%2 == 0){
obj.wait();
}
System.out.println("t1 -> " + i++);
obj.notify();
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable(){
#Override
public void run() {
while(i<10){
synchronized (obj) {
try {
if(i%2 != 0){
obj.wait();
}
System.out.println("t2 -> " + i++);
obj.notify();
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Categories