I am trying to implement Bully Algorithm in Java using threads.
Here is the code which I have written.
package newbully;
public class NewBully {
public static void main(String[] args) {
int total_processes = 4;
Thread1[] t = new Thread1[total_processes];
for (int i = 0; i < total_processes; i++) {
t[i] = new Thread1(new Process(i+1, i+1), total_processes);
}
try {
Election.initialElection(t);
} catch (Exception e) {
System.out.println("Possibly you are using null references in array");
}
for (int i = 0; i < total_processes; i++) {
new Thread(t[i]).start();
}
}
}
package newbully;
public class Election {
private static boolean pingFlag = false;
private static boolean electionFlag = false;
private static boolean messageFlag = false;
public static boolean isMessageFlag() {
return messageFlag;
}
public static void setMessageFlag(boolean messageFlag) {
Election.messageFlag = messageFlag;
}
public static boolean isPingFlag() {
return pingFlag;
}
public static void setPingFlag(boolean pingFlag) {
Election.pingFlag = pingFlag;
}
public static boolean isElectionFlag() {
return electionFlag;
}
public static void setElectionFlag(boolean electionFlag) {
Election.electionFlag = electionFlag;
}
public static void initialElection(Thread1[] t) {
Process temp = new Process(-1, -1);
for (int i = 0; i < t.length; i++) {
if (temp.getPriority() < t[i].getProcess().getPriority()) {
temp = t[i].getProcess();
}
}
t[temp.pid - 1].getProcess().CoOrdinatorFlag = true;
}
}
package newbully;
public class Process {
int pid;
boolean downflag,CoOrdinatorFlag;
public boolean isCoOrdinatorFlag() {
return CoOrdinatorFlag;
}
public void setCoOrdinatorFlag(boolean isCoOrdinator) {
this.CoOrdinatorFlag = isCoOrdinator;
}
int priority;
public boolean isDownflag() {
return downflag;
}
public void setDownflag(boolean downflag) {
this.downflag = downflag;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public Process() {
}
public Process(int pid, int priority) {
this.pid = pid;
this.downflag = false;
this.priority = priority;
this.CoOrdinatorFlag = false;
}
}
package newbully;
import java.util.*;
import java.io.*;
import java.net.*;
public class Thread1 implements Runnable {
private Process process;
private int total_processes;
ServerSocket[] sock;
Random r;
public Process getProcess() {
return process;
}
public void setProcess(Process process) {
this.process = process;
}
public Thread1(Process process, int total_processes) {
this.process = process;
this.total_processes = total_processes;
this.r = new Random();
this.sock = new ServerSocket[total_processes];
}
private void recovery() {
}
synchronized private void pingCoOrdinator() {
try {
if (Election.isPingFlag()) {
wait();
}
if (!Election.isElectionFlag()) {
Election.setPingFlag(true);
System.out.println("Process[" + this.process.getPid() + "]: Are you alive?");
Socket outgoing = new Socket(InetAddress.getLocalHost(), 12345);
outgoing.close();
Election.setPingFlag(false);
notifyAll();
}
} catch (Exception ex) {
//Initiate Election
System.out.println("process[" + this.process.getPid() + "]: -> Co-Ordinator is down\nInitiating Election");
Election.setElectionFlag(true);
Election.setPingFlag(false);
notifyAll();
}
}
synchronized private void executeJob() {
int temp = r.nextInt(20);
for (int i = 0; i <= temp; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Error Executing Thread:" + process.getPid());
System.out.println(e.getMessage());
}
}
}
synchronized private boolean sendMessage() {
boolean response = false;
int i = 0;
try {
if (Election.isMessageFlag()) {
wait();
}
Election.setMessageFlag(true);
for (i = this.process.getPid() + 1; i <= this.total_processes; i++) {
try {
Socket electionMessage = new Socket(InetAddress.getLocalHost(), 10000 + i);
System.out.println("Process[" + this.process.getPid() + "] -> Process[" + i + "] responded to election message successfully");
electionMessage.close();
response = true;
} catch (Exception ex) {
System.out.println("Process[" + this.process.getPid() + "] -> Process[" + i + "] did not respond to election message");
}
}
Election.setMessageFlag(false);
notifyAll();
} catch (Exception ex1) {
System.out.println(ex1.getMessage());
}
return response;
}
synchronized private void serve() {
try {
//service counter
ServerSocket s = new ServerSocket(12345);
for (int counter = 0; counter <= 10; counter++) {
Socket incoming = s.accept();
System.out.println("Process[" + this.process.getPid() + "]:Yes");
Scanner scan = new Scanner(incoming.getInputStream());
PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
if (scan.hasNextLine()) {
if (scan.nextLine().equals("Who is the co-ordinator?")) {
System.out.print("Process[" + this.process.getPid() + "]:");
out.println(this.process);
}
}
if (counter == 10) {//after serving 10 requests go down
this.process.setCoOrdinatorFlag(false);
this.process.setDownflag(true);
try {
incoming.close();
s.close();
sock[this.process.getPid() - 1].close();
Thread.sleep((this.r.nextInt(10) + 1) * 50000);//going down
recovery();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
#Override
public void run() {
try {
sock[this.process.getPid() - 1] = new ServerSocket(10000 + this.process.getPid());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
while (true) {
if (process.isCoOrdinatorFlag()) {
//serve other processes
serve();
} else {
while (true) {
//Execute some task
executeJob();
//Ping the co-ordinator
pingCoOrdinator();
if (Election.isElectionFlag()) {
if (!sendMessage()) {//elect self as co-ordinator
System.out.println("New Co-Ordinator: Process[" + this.process.getPid() + "]");
this.process.setCoOrdinatorFlag(true);
Election.setElectionFlag(false);
break;
}
}
}
}
}
}
}
When I am trying to execute the code out of the 4 threads which I have created some threads are waiting premanently using wait() call. They are not being notified by notifyAll(). Can anyone suggest why this is happening?
Each thread is calling wait() on itself (on its own Thread1 instance). That means that when you call notifyAll() on that same Thread1 instance, only the single Thread1 that is waiting it will be notified, and not all the other threads.
What you have to do is make all your Thread1 objects call wait() on a single, common object, and also call notifyAll() on that same object.
Ofcourse you have to synchronize on the common object when you call wait() or notifyAll() on it; if you don't do that, you'll get an IllegalMonitorStateException.
// Object to be used as a lock; pass this to all Thread1 instances
Object lock = new Object();
// Somewhere else in your code
synchronized (lock) {
lock.wait();
}
// Where you want to notify
synchronized (lock) {
lock.notifyAll();
}
Both notify() (or notifyAll()) and wait() must be written into synchronized block on the same monitor.
For example:
synchronized(myLock) {
wait();
}
..................
synchronized(myLock) {
notifyAll();
}
Related
Java producer-consumer program using thread & synchronized queue, the program is separated into 3 classes but it couldn't be run.
Queue.java:
public class Queue {
static final int MAXQUEUE = 3;
int[] queue = new int[MAXQUEUE];
int front, rear;
public Queue(){ front = 0; rear = 0; }
public boolean isEmpty(){ return (front==rear); }
public boolean isFull(){
int index = rear+1 < MAXQUEUE ? rear+1 : 0;
return (index == front);
}
public void enqueue(int value) {
queue[rear] = value;
rear = rear+1 < MAXQUEUE ? rear+1 : 0;
}
public int dequeue(){
int data = queue[front];
front = front+1 < MAXQUEUE ? rear+1 : 0;
return data;
}
}
SynchronizedQueue.java:
import java.util.Queue;
public class SynchronizedQueue {
Queue queue;
public SynchronizedQueue() {queue = new Queue(); }
public synchronized void enqueue(int value) {
try {
while (queue.isFull()) {
System.out.println();
System.out.println("Queue is full, please wait....");
wait();
}
}
catch (InterruptedException e) { }
((SynchronizedQueue) queue).enqueue(value);
notify();
}
public synchronized int dequeue() {
try {
while (queue.isEmpty()) {
System.out.println();
System.out.println("Queue is empty, please wait....");
wait();
}
}
catch ( InterruptedException e ) { }
int data = ((SynchronizedQueue) queue).dequeue();
notify();
return data;
}
}
Main program Ch10_3.java:
class Producer extends Thread {
public int count = 0;
public void run() {
int value;
while ( Ch10_3.isRunning ) {
value = (int)(Math.random()*100);
Ch10_3.squeue.enqueue(value);
System.out.print(">" + value + "]");
count++;
try {
Thread.sleep((int)(Math.random()*100));
}
catch( InterruptedException e) { }
}
System.out.println("\n" + Thread.currentThread() + "Producer thread end.");
}
}
class Consumer extends Thread {
public int count = 0;
public void run() {
int data;
while (Ch10_3.isRunning) {
data = Ch10_3.squeue.dequeue();
System.out.println("[" + data + ">");
count++;
try {
Thread.sleep((int)(Math.random()*100));
}
catch( InterruptedException e) { }
}
System.out.println("\n" + Thread.currentThread() + "Consumer thread end.");
}
}
public class Ch10_3 {
static final int MAXITEMS = 10;
static SynchonizedQueue squeue = new SynchronizedQueue();
static boolean isRunning = true;
public static void main(String[] args) {
Producer producer = new Producer();
Consumer consumer = new Consumer();
producer.start(); consumer.start();
while (true)
if (producer.count >= MAXITEMS && producer.count == consumer.count)
{ isRunning = false; break; }
}
}
Error message:
Exception in thread "main" java.lang.Error: Unresolved compilation
problem: at Ch10_3.main(Ch10_3.java:41)
In the catch blocks from enqueue and dequeue methods form class SynchronizedQueue you are trying to cast the queue member attribute which is of type Queue, to SynchronizedQueue.
In SynchronizedQueue.enqueue() we have:
((SynchronizedQueue) queue).enqueue(value);
Since there is no relation between Queue and SynchronizedQueue the compiler gives a compilation error. You should remove the cast.
But the best solution is to just use a java.util.concurrent.BlockingQueue implementation available in JAVA SDK, which will handle all the synchronisation part for you.
I am learning multithreading. I am implementing producer and consumer problem. I am stuck on scenario where i want that when I press anything apart from integer from keyboard, all my threads should die and there is no memory in use by threads. Please have your valuable inputs to help me achieve it. Below is all the code I am using.
package com.java.concurrency;
public class ThreadSignaling {
private int i = -1;
private boolean valueSet = false;
private boolean stopFlag = false;
public void put(int value) {
synchronized (this) {
while (valueSet) {
if (stopFlag) {
System.out.println("Byeeeeeeeeeeeee");
break;
}
try {
this.wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException while waiting in put() : " + e);
}
}
this.i = value;
this.valueSet = true;
System.out.println("Value put : " + this.i);
this.notify();
}
}
public void get() {
synchronized (this) {
while (!valueSet) {
if (stopFlag) {
System.out.println("Byeeeeeeeeeeeee");
break;
}
try {
this.wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException while waiting in get() : " + e);
}
}
System.out.println("Value get : " + this.i);
valueSet = false;
this.notify();
}
}
public void finish() {
synchronized (this) {
stopFlag = true;
this.notifyAll();
}
}
}
public class Producer implements Runnable {
private ThreadSignaling sharedObj = null;
private final Scanner input = new Scanner(System.in);
public Producer(ThreadSignaling obj) {
this.sharedObj = obj;
}
#Override
public void run() {
int value = -1;
System.out.println("Press Ctrl-c to stop... ");
while (true) {
System.out.println("Enter any integer value : ");
if (input.hasNextInt()) {
value = input.nextInt();
} else {
this.sharedObj.finish();
return;
}
this.sharedObj.put(value);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("InterruptedException while sleeping" + e);
}
}
}
}
public class Consumer implements Runnable {
private ThreadSignaling sharedObj = null;
public Consumer(ThreadSignaling obj) {
this.sharedObj = obj;
}
#Override
public void run() {
while (true) {
this.sharedObj.get();
}
}
}
public class MainThread {
public static void main(String[] args) {
ThreadSignaling sharedObj = new ThreadSignaling();
Producer in = new Producer(sharedObj);
Consumer out = new Consumer(sharedObj);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
} enter code here
The problem with your code is that you do not have an exit condition for the Consumer. The run() method of the Consumer will run forever, and while doing repeated get calls on the shared object.
What you need to do is to make aware the Consumer that the Producer has set the stopFlag in the shared object. And if that stopFlag is true then the loop in the Consumer should also finish. There are several ways you can do that:
redefine get method to return the value of stopFlag;
define a new method to return just the value of stopFlag;
In either cases, make a test in the Consumer.run() and if the value is true, just do a return so the infinite loop ends.
I have a problem with possible deadlock in "producer - consumer task".
Everything should be working in following way:
Producer should generate and add int[] arrays to collection
Consumer should take those arrays, put them to second collection and print in output
In debbug mode I have noticed that after a while both taks are suspended on this.wait(); method.
Could you help me and explain what is wrong with this code? :)
Thanks!
Producer task class
public class ProducerTask extends Thread{
private static final Object bufforLock = new Object();
private static LinkedList<Integer[]> buffor;
public ProducerTask(){
if(buffor == null)
buffor = new LinkedList<>();
this.setName("#ProducerTask");
}
#Override
public void run() {
synchronized (this) {
try {
for (int i = 0; i < 100; i++) {
while (isBufforFull()) {
System.err.println("ProducerTask is waiting");
this.wait();
}
Integer[] randomIntArray = getRandomIntArray();
addToBuffor(randomIntArray);
}
}
catch (InterruptedException ex) {
}
}
}
public static void removeLast(){
synchronized(bufforLock){
buffor.removeLast();
bufforLock.notifyAll();
}
}
public static Integer[] getLast(){
synchronized(bufforLock){
return buffor.getLast();
}
}
public static boolean isBufforFull(){
synchronized(bufforLock){
return buffor.size() == 10;
}
}
public static boolean isBufforEmpty(){
synchronized(bufforLock){
return buffor.isEmpty();
}
}
public static void addToBuffor(Integer[] array){
synchronized(bufforLock){
buffor.addFirst(array);
bufforLock.notifyAll();
}
}
public static LinkedList<Integer[]> getBuffor(){
synchronized(bufforLock){
return buffor;
}
}
private Integer[] getRandomIntArray(){
int maxSize = 10;
Integer[] array = new Integer[maxSize];
for(int i = 0 ; i < maxSize ; i++){
int value = (int) (Math.random() * 100);
array[i] = Integer.valueOf(value);
}
return array;
}
}
Consumer task class
public class ConsumerTask extends Thread {
private static LinkedList<Integer[]> buffor;
public ConsumerTask() {
if (buffor == null) {
buffor = new LinkedList<>();
}
this.setName("#ConsumerTask");
}
#Override
public void run() {
synchronized (this) {
try {
while (true) {
while (ProducerTask.isBufforEmpty()) {
System.err.println("ConsumerTask is waiting");
this.wait();
}
Integer[] array = ProducerTask.getLast();
this.arraySortByInserting(array);
this.buffor.addFirst(array);
ProducerTask.removeLast();
}
}
catch (InterruptedException ex) {}
}
}
private Integer[] arraySortByInserting(Integer[] aArrayToSort) {
if(aArrayToSort == null || aArrayToSort.length == 0)
return null;
this.printArray(aArrayToSort, "Array before sorting");
for (int i = 1; i < aArrayToSort.length; i++) {
int intValue = aArrayToSort[i];
int j = i;
while ((j > 0) && (aArrayToSort[j - 1] > intValue)) {
aArrayToSort[j] = aArrayToSort[j - 1];
j--;
}
aArrayToSort[j] = intValue;
}
this.printArray(aArrayToSort, "Array after sorting");
return aArrayToSort;
}
private void printArray(Integer[] aArray, String aMessage) {
System.out.print(aMessage + " [");
for (int intElement : aArray) {
System.out.print(intElement + " ");
}
System.out.print("]");
System.out.println();
}
}
You need a common object which would be used for inter thread communication.
Right now you are using this as object on which you get lock on and you notify on bufferLock in producer thread and same applies for consumer thread.
Remember both are two different instances and both successfully obtain lock on individual objects and then both enters wait state.
Odd even number printing using thread.Create one thread class, two instance of the thread. One will print the odd number and the other will print the even number.
I did the following coding. But it comes to dead lock state. Can some one please explain what might be the reason for that?
public class NumberPrinter implements Runnable{
private String type;
private static boolean oddTurn=true;
public NumberPrinter(String type){
this.type=type;
}
public void run() {
int i=type.equals("odd")?1:2;
while(i<10){
if(type.equals("odd"))
printOdd(i);
if(type.equals("even"))
printEven(i);
i=i+2;
}
}
private synchronized void printOdd(int i){
while(!oddTurn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + i);
oddTurn=false;
notifyAll();
}
private synchronized void printEven(int i){
while(oddTurn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + i);
oddTurn=true;
notifyAll();
}
public static void main(String[] s){
Thread odd=new Thread(new NumberPrinter("odd"));
Thread even=new Thread(new NumberPrinter("even"));
odd.start();
even.start();
}
}
Out Put:
odd1
even2
then comes to deadlock!!!!!!
Thanks for your help.
You're waiting and notifying different objects (monitors).
The idea is that you can call obj.wait() to wait for someone to do obj.notify(), while you're doing objA.wait() and objB.notify().
Change your printOdd method to something like
private void printOdd(int i) {
synchronized (lock) { // <-------
while (!oddTurn) {
try {
lock.wait(); // <-------
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + i);
oddTurn = false;
lock.notifyAll(); // <-------
}
}
and the printEven method similarly.
Then provide the NumberPrinter with a lock object:
Object lock = new Object();
Thread odd = new Thread(new NumberPrinter("odd", lock));
Thread even = new Thread(new NumberPrinter("even", lock));
Output:
odd1
even2
odd3
even4
odd5
even6
odd7
even8
odd9
There are a lot of bugs in the code.
First of all, the synchronized statements have no effect whatsoever. You create two thread instances, and each calls only its own methods. synchronized is only useful if another thread can call a method.
Then notifyAll() has no effect for the same reasons. odd.notifyAll() doesn't reach even hanging in the wait().
So what you need is another object which contains the state and which both threads can see and use. Use synchronized, wait() and notifyAll() on that third instance.
The same can be solved using Lock interface:
NaturalOrder.java
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NaturalOrder {
public int currentNumber = 1;
public boolean evenOdd = false;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public static void main(String[] args) {
NaturalOrder naturalOrder = new NaturalOrder();
Thread t1 = new Thread(new OddNumberLock(naturalOrder, naturalOrder.lock, naturalOrder.condition));
Thread t2 = new Thread(new EvenNumberLock(naturalOrder, naturalOrder.lock, naturalOrder.condition));
t1.start();
t2.start();
}
}
OddNumberLock.java
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class OddNumberLock implements Runnable {
NaturalOrder naturalOrder;
Lock lock;
Condition condition;
public OddNumberLock(NaturalOrder naturalOrder, Lock lock, Condition condition) {
this.naturalOrder = naturalOrder;
this.lock = lock;
this.condition = condition;
}
#Override
public void run() {
lock.lock();
while (naturalOrder.currentNumber < 20) {
while (naturalOrder.evenOdd != false) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (naturalOrder.currentNumber % 2 != 0) {
System.out.println(naturalOrder.currentNumber);
}
naturalOrder.currentNumber++;
naturalOrder.evenOdd = true;
condition.signalAll();
}
lock.unlock();
}
}
EvenNumberLock.java
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class EvenNumberLock implements Runnable {
NaturalOrder naturalOrder;
Lock lock;
Condition condition;
public EvenNumberLock(NaturalOrder naturalOrder, Lock lock, Condition condition) {
this.naturalOrder = naturalOrder;
this.lock = lock;
this.condition = condition;
}
#Override
public void run() {
lock.lock();
while (naturalOrder.currentNumber < 20) {
while (naturalOrder.evenOdd != true) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (naturalOrder.currentNumber % 2 == 0) {
System.out.println(naturalOrder.currentNumber);
}
naturalOrder.currentNumber++;
naturalOrder.evenOdd = false;
condition.signalAll();
}
lock.unlock();
}
}
I think the problem might be that printOdd and printEven synchronize on different lock (the Thread's object instance locks). Therefor you have not guaranteed that the change on the static variable oddTurn will be visible in the other thread. Try to make the oddTurn volatile for the start.
I did this way
public class OddEven{
public static void main(String[] args){
Print o=new Print();
Thread even=new Thread(new MyRunnable(2,o));
Thread odd=new Thread(new MyRunnable(1,o));
even.start();
odd.start();
}
}
class MyRunnable implements Runnable{
int start;
Print ob;
MyRunnable(int s,Print o){
start=s;
ob=o;
}
public void run(){
for(int i=start;i<=20;i+=2)
ob.display(i);
}
}
class Print{
int rem=0;
synchronized void display(int n){
while(n%2==rem)
try{
wait();
}
catch(Exception e){System.out.println("Display interrupted");}
System.out.print(n+" ");
rem=n%2;
notify();
}
}
You're missing volatile keyword within oddTurn variable. Without it there are no guarantees the threads see the actual value.
i Used a shared object to control the order of execution
class Counter implements Runnable {
int count;
static Class cl = Counter.class;
public synchronized void increment() {
String tname = Thread.currentThread().getName();
System.out.printf("%s: %d\n", tname, count++);
}
#Override
public void run() {
String tname = Thread.currentThread().getName();
while (true) {
increment();
synchronized (Counter.class) {
try {
cl.notify();
cl.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public class WaitNotify {
public static void main(String[] args) {
Counter c = new Counter();
Thread t1 = new Thread(c, "thread1");
Thread t2 = new Thread(c, "thread2");
t1.start();
t2.start();
}
}
Here's my solution without any waits or notify.
wait() and notify()/notifyAll() ,
I dont see any reason to use them for this problem statement.
package threading;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EvenOddPrinting {
int count=0;
boolean isOdd = false;
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
EvenOddPrinting obj = new EvenOddPrinting();
exec.submit(new EvenPrinter(obj));
exec.submit(new OddPrinter(obj));
exec.shutdown();
}
}
class EvenPrinter implements Runnable{
EvenOddPrinting obj;
public EvenPrinter(EvenOddPrinting obj) {
this.obj=obj;
}
#Override
public void run() {
while(obj.count < 100){
if(!obj.isOdd){
System.out.println("Even:"+obj.count);
obj.count++;
obj.isOdd = true;
}
}
}
}
class OddPrinter implements Runnable{
EvenOddPrinting obj;
public OddPrinter(EvenOddPrinting obj) {
this.obj = obj;
}
#Override
public void run() {
while(obj.count < 100){
if(obj.isOdd){
System.out.println("Odd:"+obj.count);
obj.count++;
obj.isOdd = false;
}
}
}
}
Your code corrected with using Lock interface:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NumberPrinter implements Runnable {
private Lock lock;
private Condition condition;
private String type;
private static boolean oddTurn = true;
public NumberPrinter(String type, Lock lock, Condition condition) {
this.type = type;
this.lock = lock;
this.condition = condition;
}
public void run() {
int i = type.equals("odd") ? 1 : 2;
while (i <= 10) {
if (type.equals("odd"))
printOdd(i);
if (type.equals("even"))
printEven(i);
i = i + 2;
}
}
private void printOdd(int i) {
// synchronized (lock) {
lock.lock();
while (!oddTurn) {
try {
// lock.wait();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + " " + i);
oddTurn = false;
// lock.notifyAll();
condition.signalAll();
lock.unlock();
}
// }
private void printEven(int i) {
// synchronized (lock) {
lock.lock();
while (oddTurn) {
try {
// lock.wait();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + " " + i);
oddTurn = true;
// lock.notifyAll();
condition.signalAll();
lock.unlock();
}
// }
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Thread odd = new Thread(new NumberPrinter("odd", lock, condition));
Thread even = new Thread(new NumberPrinter("even", lock, condition));
odd.start();
even.start();
}
}
public class Number_Thread extends Thread {
String thread;
int limit;
public Number_Thread(String thread,int limit){
this.thread=thread;
this.limit=limit;
}
Object lock=new Object();
public void run()
{
synchronized (lock)
{
//------------------- "print even"--------------------//
if(thread.equals("even"))
{
for (int i = 2; i <=limit; i+=2)
{
System.out.println(thread+" thread "+i);
try {
lock.wait(1000);
continue;
}
catch (InterruptedException e) {}
}
lock.notifyAll();
}
//------------------- "print odd"--------------------//
if(thread.equals("odd"))
{
for (int i = 1; i <=limit; i+=2)
{
System.out.println(thread+" thread "+i);
try {
lock.wait(1000);
continue;
}
catch (InterruptedException e) {}
}
lock.notifyAll();
}
}
}
}
//------------------thread creater class------------------//
import java.util.Scanner;
public class Main_Thread {
private static Scanner s;
public static void main(String[] args) throws InterruptedException {
System.out.print("enter limit:\t ");
s=new Scanner(System.in);
int n=s.nextInt();
s.close();
Thread t1=new Number_Thread("even",n);
Thread t2=new Number_Thread("odd",n);
t2.start();
Thread.sleep(100);
t1.start();
}
}
output for limit 5:
enter limit: 5
odd thread 1
even thread 2
odd thread 3
even thread 4
odd thread 5
I have implemented in such a way, based on the argument, no of threads will be spawned and will the respective no in round robin manner.
i.e., If thread count is 3, thread 1 will print 1,4 ...; thread 2 will print 2,5,... and thread 3 will print 3,6...
public class ThreadSynchronizer
{
public static void main(String[] args)
{
// BASED ON THE ARGUMENT MULTIPLE THREADS WILL BE CREATED AND EACH WILL PRINT ITS RESPECTIVE NO
// IE, IF THREAD COUNT IS 3, THREAD 1 WILL PRINT 1,4 ..., THREAD2 WILL PRINT 2,5,... AND THREAD3 WILL PRINT 3,6...
// LIMITED THE DISPLAY TO 1000 NOS
int threadCnt = Integer.parseInt(args[0]);
ReentrantLock lckArray[] = new ReentrantLock[threadCnt + 1];
for (int i = 0; i < threadCnt + 1; i++)
{
ReentrantLock lck = new ReentrantLock();
lck.lock();
lckArray[i] = lck;
}
for (int i = 0; i < threadCnt; i++)
{
Thread th = new Thread(new Printer(lckArray, i + 1));
th.start();
}
for (int i = 1; i < threadCnt + 1; i++)
{
lckArray[i].unlock();
while (!lckArray[i].isLocked())
{
}
}
lckArray[0].unlock();
}
}
class Printer implements Runnable
{
private ReentrantLock[] lckArray;
private int index;
Printer(ReentrantLock[] lckArray, int startValue)
{
this.lckArray = lckArray;
this.index = startValue;
}
#Override public void run()
{
ReentrantLock prevLock = null;
int printCounter = index;
for (int counter = 0; printCounter <= 1000; counter++)
{
int remCounter = counter % lckArray.length;
int incCounter = lckArray.length - remCounter;
int indexPostion = index + incCounter;
int curElementIndex = indexPostion % lckArray.length;
lckArray[curElementIndex].lock();
if (prevLock != null)
prevLock.unlock();
prevLock = lckArray[curElementIndex];
if (curElementIndex == 0)
{
System.out.println("Printed by Thread " + index + " " + printCounter);
printCounter = printCounter + lckArray.length - 1;
}
}
if (prevLock != null)
{
if (prevLock.isHeldByCurrentThread())
prevLock.unlock();
}
}
}
Program for Two Threads Alternatively Print Odd and Even Numbers.
#Implemented Using "Object Lock" Concept.
class Increment{
private int count;
public void increment(){
count++;
System.out.println(Thread.currentThread().getName()+"::::::::::::::::::"+count);
}
}
class SimpleThread extends Thread{
Increment obj = null;
SimpleThread(Increment obj){
this.obj=obj;
}
public void run(){
try {
Thread.sleep(100);
while(true){
synchronized(obj){
obj.increment();
Thread.sleep(1000);
obj.notify();
obj.wait();
}
}
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
public class Main
{
public static void main(String[] args) {
Increment increment = new Increment();
SimpleThread t1 = new SimpleThread(increment);
SimpleThread t2 = new SimpleThread(increment);
t1.start();
t2.start();
System.out.println(Thread.currentThread().getName()+"::::::::::::::"+"Hello World");
System.out.println(Runtime.getRuntime().availableProcessors()+"::::::::::::::"+"CORE SIZE");
}
}
I implemented it in a very simple way, from 1 to 40>
public class EvenOddProblem {
public static void main(String[] args) {
Printer p = new Printer();
EvenThread enenThread = new EvenThread(p);
OddThread oddThread = new OddThread(p);
new Thread(enenThread).start();
new Thread(oddThread).start();
}
}
class EvenThread implements Runnable {
private Printer printer;
public EvenThread(Printer p) {
printer = p;
}
#Override
public void run() {
try {
int i = 0;
while (true) {
if (i == 20)
break;
i++;
printer.evenPrintEven();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class OddThread implements Runnable {
private Printer printer;
public OddThread(Printer p) {
printer = p;
}
#Override
public void run() {
int i = 0;
try {
while (true) {
if (i == 20)
break;
i++;
printer.evenPrintOdd();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Printer {
private static volatile Integer i = 1;
public synchronized void evenPrintOdd() throws InterruptedException {
while (i % 2 == 0) {
wait();
}
System.out.println(i);
i++;
notifyAll();
}
public synchronized void evenPrintEven() throws InterruptedException {
while (!(i % 2 == 0)) {
wait();
}
System.out.println(i);
i++;
notifyAll();
}
}
Odd even number printing using thread.Create one thread class, two instance of the thread. One will print the odd number and the other will print the even number.
I did the following coding. But it comes to dead lock state. Can some one please explain what might be the reason for that?
public class NumberPrinter implements Runnable{
private String type;
private static boolean oddTurn=true;
public NumberPrinter(String type){
this.type=type;
}
public void run() {
int i=type.equals("odd")?1:2;
while(i<10){
if(type.equals("odd"))
printOdd(i);
if(type.equals("even"))
printEven(i);
i=i+2;
}
}
private synchronized void printOdd(int i){
while(!oddTurn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + i);
oddTurn=false;
notifyAll();
}
private synchronized void printEven(int i){
while(oddTurn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + i);
oddTurn=true;
notifyAll();
}
public static void main(String[] s){
Thread odd=new Thread(new NumberPrinter("odd"));
Thread even=new Thread(new NumberPrinter("even"));
odd.start();
even.start();
}
}
Out Put:
odd1
even2
then comes to deadlock!!!!!!
Thanks for your help.
You're waiting and notifying different objects (monitors).
The idea is that you can call obj.wait() to wait for someone to do obj.notify(), while you're doing objA.wait() and objB.notify().
Change your printOdd method to something like
private void printOdd(int i) {
synchronized (lock) { // <-------
while (!oddTurn) {
try {
lock.wait(); // <-------
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + i);
oddTurn = false;
lock.notifyAll(); // <-------
}
}
and the printEven method similarly.
Then provide the NumberPrinter with a lock object:
Object lock = new Object();
Thread odd = new Thread(new NumberPrinter("odd", lock));
Thread even = new Thread(new NumberPrinter("even", lock));
Output:
odd1
even2
odd3
even4
odd5
even6
odd7
even8
odd9
There are a lot of bugs in the code.
First of all, the synchronized statements have no effect whatsoever. You create two thread instances, and each calls only its own methods. synchronized is only useful if another thread can call a method.
Then notifyAll() has no effect for the same reasons. odd.notifyAll() doesn't reach even hanging in the wait().
So what you need is another object which contains the state and which both threads can see and use. Use synchronized, wait() and notifyAll() on that third instance.
The same can be solved using Lock interface:
NaturalOrder.java
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NaturalOrder {
public int currentNumber = 1;
public boolean evenOdd = false;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public static void main(String[] args) {
NaturalOrder naturalOrder = new NaturalOrder();
Thread t1 = new Thread(new OddNumberLock(naturalOrder, naturalOrder.lock, naturalOrder.condition));
Thread t2 = new Thread(new EvenNumberLock(naturalOrder, naturalOrder.lock, naturalOrder.condition));
t1.start();
t2.start();
}
}
OddNumberLock.java
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class OddNumberLock implements Runnable {
NaturalOrder naturalOrder;
Lock lock;
Condition condition;
public OddNumberLock(NaturalOrder naturalOrder, Lock lock, Condition condition) {
this.naturalOrder = naturalOrder;
this.lock = lock;
this.condition = condition;
}
#Override
public void run() {
lock.lock();
while (naturalOrder.currentNumber < 20) {
while (naturalOrder.evenOdd != false) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (naturalOrder.currentNumber % 2 != 0) {
System.out.println(naturalOrder.currentNumber);
}
naturalOrder.currentNumber++;
naturalOrder.evenOdd = true;
condition.signalAll();
}
lock.unlock();
}
}
EvenNumberLock.java
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class EvenNumberLock implements Runnable {
NaturalOrder naturalOrder;
Lock lock;
Condition condition;
public EvenNumberLock(NaturalOrder naturalOrder, Lock lock, Condition condition) {
this.naturalOrder = naturalOrder;
this.lock = lock;
this.condition = condition;
}
#Override
public void run() {
lock.lock();
while (naturalOrder.currentNumber < 20) {
while (naturalOrder.evenOdd != true) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (naturalOrder.currentNumber % 2 == 0) {
System.out.println(naturalOrder.currentNumber);
}
naturalOrder.currentNumber++;
naturalOrder.evenOdd = false;
condition.signalAll();
}
lock.unlock();
}
}
I think the problem might be that printOdd and printEven synchronize on different lock (the Thread's object instance locks). Therefor you have not guaranteed that the change on the static variable oddTurn will be visible in the other thread. Try to make the oddTurn volatile for the start.
I did this way
public class OddEven{
public static void main(String[] args){
Print o=new Print();
Thread even=new Thread(new MyRunnable(2,o));
Thread odd=new Thread(new MyRunnable(1,o));
even.start();
odd.start();
}
}
class MyRunnable implements Runnable{
int start;
Print ob;
MyRunnable(int s,Print o){
start=s;
ob=o;
}
public void run(){
for(int i=start;i<=20;i+=2)
ob.display(i);
}
}
class Print{
int rem=0;
synchronized void display(int n){
while(n%2==rem)
try{
wait();
}
catch(Exception e){System.out.println("Display interrupted");}
System.out.print(n+" ");
rem=n%2;
notify();
}
}
You're missing volatile keyword within oddTurn variable. Without it there are no guarantees the threads see the actual value.
i Used a shared object to control the order of execution
class Counter implements Runnable {
int count;
static Class cl = Counter.class;
public synchronized void increment() {
String tname = Thread.currentThread().getName();
System.out.printf("%s: %d\n", tname, count++);
}
#Override
public void run() {
String tname = Thread.currentThread().getName();
while (true) {
increment();
synchronized (Counter.class) {
try {
cl.notify();
cl.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public class WaitNotify {
public static void main(String[] args) {
Counter c = new Counter();
Thread t1 = new Thread(c, "thread1");
Thread t2 = new Thread(c, "thread2");
t1.start();
t2.start();
}
}
Here's my solution without any waits or notify.
wait() and notify()/notifyAll() ,
I dont see any reason to use them for this problem statement.
package threading;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EvenOddPrinting {
int count=0;
boolean isOdd = false;
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
EvenOddPrinting obj = new EvenOddPrinting();
exec.submit(new EvenPrinter(obj));
exec.submit(new OddPrinter(obj));
exec.shutdown();
}
}
class EvenPrinter implements Runnable{
EvenOddPrinting obj;
public EvenPrinter(EvenOddPrinting obj) {
this.obj=obj;
}
#Override
public void run() {
while(obj.count < 100){
if(!obj.isOdd){
System.out.println("Even:"+obj.count);
obj.count++;
obj.isOdd = true;
}
}
}
}
class OddPrinter implements Runnable{
EvenOddPrinting obj;
public OddPrinter(EvenOddPrinting obj) {
this.obj = obj;
}
#Override
public void run() {
while(obj.count < 100){
if(obj.isOdd){
System.out.println("Odd:"+obj.count);
obj.count++;
obj.isOdd = false;
}
}
}
}
Your code corrected with using Lock interface:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NumberPrinter implements Runnable {
private Lock lock;
private Condition condition;
private String type;
private static boolean oddTurn = true;
public NumberPrinter(String type, Lock lock, Condition condition) {
this.type = type;
this.lock = lock;
this.condition = condition;
}
public void run() {
int i = type.equals("odd") ? 1 : 2;
while (i <= 10) {
if (type.equals("odd"))
printOdd(i);
if (type.equals("even"))
printEven(i);
i = i + 2;
}
}
private void printOdd(int i) {
// synchronized (lock) {
lock.lock();
while (!oddTurn) {
try {
// lock.wait();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + " " + i);
oddTurn = false;
// lock.notifyAll();
condition.signalAll();
lock.unlock();
}
// }
private void printEven(int i) {
// synchronized (lock) {
lock.lock();
while (oddTurn) {
try {
// lock.wait();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + " " + i);
oddTurn = true;
// lock.notifyAll();
condition.signalAll();
lock.unlock();
}
// }
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Thread odd = new Thread(new NumberPrinter("odd", lock, condition));
Thread even = new Thread(new NumberPrinter("even", lock, condition));
odd.start();
even.start();
}
}
public class Number_Thread extends Thread {
String thread;
int limit;
public Number_Thread(String thread,int limit){
this.thread=thread;
this.limit=limit;
}
Object lock=new Object();
public void run()
{
synchronized (lock)
{
//------------------- "print even"--------------------//
if(thread.equals("even"))
{
for (int i = 2; i <=limit; i+=2)
{
System.out.println(thread+" thread "+i);
try {
lock.wait(1000);
continue;
}
catch (InterruptedException e) {}
}
lock.notifyAll();
}
//------------------- "print odd"--------------------//
if(thread.equals("odd"))
{
for (int i = 1; i <=limit; i+=2)
{
System.out.println(thread+" thread "+i);
try {
lock.wait(1000);
continue;
}
catch (InterruptedException e) {}
}
lock.notifyAll();
}
}
}
}
//------------------thread creater class------------------//
import java.util.Scanner;
public class Main_Thread {
private static Scanner s;
public static void main(String[] args) throws InterruptedException {
System.out.print("enter limit:\t ");
s=new Scanner(System.in);
int n=s.nextInt();
s.close();
Thread t1=new Number_Thread("even",n);
Thread t2=new Number_Thread("odd",n);
t2.start();
Thread.sleep(100);
t1.start();
}
}
output for limit 5:
enter limit: 5
odd thread 1
even thread 2
odd thread 3
even thread 4
odd thread 5
I have implemented in such a way, based on the argument, no of threads will be spawned and will the respective no in round robin manner.
i.e., If thread count is 3, thread 1 will print 1,4 ...; thread 2 will print 2,5,... and thread 3 will print 3,6...
public class ThreadSynchronizer
{
public static void main(String[] args)
{
// BASED ON THE ARGUMENT MULTIPLE THREADS WILL BE CREATED AND EACH WILL PRINT ITS RESPECTIVE NO
// IE, IF THREAD COUNT IS 3, THREAD 1 WILL PRINT 1,4 ..., THREAD2 WILL PRINT 2,5,... AND THREAD3 WILL PRINT 3,6...
// LIMITED THE DISPLAY TO 1000 NOS
int threadCnt = Integer.parseInt(args[0]);
ReentrantLock lckArray[] = new ReentrantLock[threadCnt + 1];
for (int i = 0; i < threadCnt + 1; i++)
{
ReentrantLock lck = new ReentrantLock();
lck.lock();
lckArray[i] = lck;
}
for (int i = 0; i < threadCnt; i++)
{
Thread th = new Thread(new Printer(lckArray, i + 1));
th.start();
}
for (int i = 1; i < threadCnt + 1; i++)
{
lckArray[i].unlock();
while (!lckArray[i].isLocked())
{
}
}
lckArray[0].unlock();
}
}
class Printer implements Runnable
{
private ReentrantLock[] lckArray;
private int index;
Printer(ReentrantLock[] lckArray, int startValue)
{
this.lckArray = lckArray;
this.index = startValue;
}
#Override public void run()
{
ReentrantLock prevLock = null;
int printCounter = index;
for (int counter = 0; printCounter <= 1000; counter++)
{
int remCounter = counter % lckArray.length;
int incCounter = lckArray.length - remCounter;
int indexPostion = index + incCounter;
int curElementIndex = indexPostion % lckArray.length;
lckArray[curElementIndex].lock();
if (prevLock != null)
prevLock.unlock();
prevLock = lckArray[curElementIndex];
if (curElementIndex == 0)
{
System.out.println("Printed by Thread " + index + " " + printCounter);
printCounter = printCounter + lckArray.length - 1;
}
}
if (prevLock != null)
{
if (prevLock.isHeldByCurrentThread())
prevLock.unlock();
}
}
}
Program for Two Threads Alternatively Print Odd and Even Numbers.
#Implemented Using "Object Lock" Concept.
class Increment{
private int count;
public void increment(){
count++;
System.out.println(Thread.currentThread().getName()+"::::::::::::::::::"+count);
}
}
class SimpleThread extends Thread{
Increment obj = null;
SimpleThread(Increment obj){
this.obj=obj;
}
public void run(){
try {
Thread.sleep(100);
while(true){
synchronized(obj){
obj.increment();
Thread.sleep(1000);
obj.notify();
obj.wait();
}
}
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
public class Main
{
public static void main(String[] args) {
Increment increment = new Increment();
SimpleThread t1 = new SimpleThread(increment);
SimpleThread t2 = new SimpleThread(increment);
t1.start();
t2.start();
System.out.println(Thread.currentThread().getName()+"::::::::::::::"+"Hello World");
System.out.println(Runtime.getRuntime().availableProcessors()+"::::::::::::::"+"CORE SIZE");
}
}
I implemented it in a very simple way, from 1 to 40>
public class EvenOddProblem {
public static void main(String[] args) {
Printer p = new Printer();
EvenThread enenThread = new EvenThread(p);
OddThread oddThread = new OddThread(p);
new Thread(enenThread).start();
new Thread(oddThread).start();
}
}
class EvenThread implements Runnable {
private Printer printer;
public EvenThread(Printer p) {
printer = p;
}
#Override
public void run() {
try {
int i = 0;
while (true) {
if (i == 20)
break;
i++;
printer.evenPrintEven();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class OddThread implements Runnable {
private Printer printer;
public OddThread(Printer p) {
printer = p;
}
#Override
public void run() {
int i = 0;
try {
while (true) {
if (i == 20)
break;
i++;
printer.evenPrintOdd();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Printer {
private static volatile Integer i = 1;
public synchronized void evenPrintOdd() throws InterruptedException {
while (i % 2 == 0) {
wait();
}
System.out.println(i);
i++;
notifyAll();
}
public synchronized void evenPrintEven() throws InterruptedException {
while (!(i % 2 == 0)) {
wait();
}
System.out.println(i);
i++;
notifyAll();
}
}