Related
myCode is following:
I want to know why zhangsan and lisi are both can print :
李四9锁对象:1522503870
张三9锁对象:1522503870
public class TicketConsumer implements Runnable {
private Integer i;
public TicketConsumer(int i) {
super();
this.i = i;
}
#Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + i + "锁对象before:" + System.identityHashCode(i));
synchronized (i) {
System.out.println(Thread.currentThread().getName() + i + "锁对象:" + System.identityHashCode(i));
if (i > 0) {
try {
Thread.sleep(100); // 模拟抢票延迟
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了第" + i-- + "张票");
} else {
return;
}
}
}
}
public static void main(String[] args) {
TicketConsumer ticket = new TicketConsumer(new Integer(10));
Thread t1 = new Thread(ticket, "张三");
Thread t2 = new Thread(ticket, "李四");
t1.start();
t2.start();
}
}
the result is :
张三10锁对象before:1417180225
李四10锁对象before:1417180225
张三10锁对象:1417180225
张三抢到了第10张票
张三9锁对象before:1522503870
李四9锁对象:1522503870
张三9锁对象:1522503870
李四抢到了第9张票
李四8锁对象before:2045992545
李四8锁对象:2045992545
张三抢到了第9张票
I want to know why 张三 and 李四 both can get:
李四9锁对象:1522503870
张三9锁对象:1522503870
I might be wrong, but when you do i--, you can see that System.identityHashCode(i) changes, so another thread that was waiting outside the synchronized block can now enter it. Synchronizing on objects that change identity/reference is not a good idea, try synchronizing on a Stack and debug with stack.push(...): that will not change reference.
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.
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();
}
}
I have tired this question, and i ended up with some doubts. Please help me out
Doubt : If any thread is in wait state , and no other thread is notifying that one , so will it never come to and end ? Even after using wait(long milliseconds).
For Code : What my requirement is from the code(Please Refer My Code) :
a : Should print "Even Thread Finish " and "Odd Thread Finish" (Order is not imp , but must print both)
b: Also in main function should print " Exit Main Thread"
What is actually happening :
After lot of runs , in some cases , it prints "Even Thread Finish" then hangs here or vice-versa. In some cases it prints both.
Also it never prints "Exit Main Thread".
So How to modify code , so it must print all 3 statement .(Of Course "Exit Main.. " in last , as i am using join for main.)
In brief : Main start-> t1 start -> t2 start ,, then i need t2/t1 finish -> main finish.
Please help me out for this problem
Here is my code :
import javax.sql.CommonDataSource;
public class ThreadTest {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Share commonObj = new Share();
Thread even = new Thread(new EvenThread(commonObj));
Thread odd = new Thread(new OddThread(commonObj));
even.start();
odd.start();
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Exit Main Thread");
}
}
class EvenThread implements Runnable {
private Share commShare;
public EvenThread(Share obj) {
// TODO Auto-generated constructor stub
this.commShare = obj;
}
private int number = 2;
public void run() {
System.out.println("Even Thread start");
while (number <= 50) {
if (commShare.flag == true) {
System.out.println("Even Thread" + number);
number += 2;
commShare.flag = false;
synchronized(commShare) {
try {
commShare.notify();
commShare.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
commShare.notify();
}
} else {
synchronized(commShare) {
try {
commShare.notify();
commShare.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
commShare.notify();
}
}
}
System.out.println("Even Thread Finish");
}
}
class OddThread implements Runnable {
private int number = 1;
private Share commShare;
public OddThread(Share obj) {
// TODO Auto-generated constructor stub
this.commShare = obj;
}
public void run() {
System.out.println("Odd Thread start");
while (number <= 50) {
if (commShare.flag == false) {
System.out.println("Odd Thread :" + number);
number += 2;
commShare.flag = true;
synchronized(commShare) {
try {
commShare.notify();
commShare.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
commShare.notify();
}
}
}
System.out.println("Odd Thread Finish");
}
}
class Share {
Share sharedObj;
public boolean flag = false;
}
Although this is not the exact answer of your question, but this implementation is an alternative of your problem .
public class EvenOddThreads {
public static void main(String[] args) {
Thread odd = new Thread(new OddThread(), "oddThread");
Thread even = new Thread(new EvenThread(), "Even Thread");
odd.start();
even.start();
try {
odd.join();
even.join();
System.out.println("Main thread exited");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class OddThread implements Runnable{
public void run() {
synchronized (CommonUtil.mLock) {
System.out.println(Thread.currentThread().getName()+"---> job starting");
int i = 1;
while(i<50){
System.out.print(i + "\t");
i = i + 2;
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("OddThread---> job completed");
CommonUtil.mLock.notify();
}
}
}
class EvenThread implements Runnable{
#Override
public void run() {
synchronized (CommonUtil.mLock) {
System.out.println(Thread.currentThread().getName()+"---> job started");
int i =2;
while(i<50){
System.out.print(i + "\t");
i = i+2;
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("EvenThread---> job completed");
CommonUtil.mLock.notify();
}
}
}
class CommonUtil{
static final Object mLock= new Object();
}
Output:
oddThread---> job starting
1 Even Thread---> job started
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 EvenThread---> job completed
OddThread---> job completed
Main thread exited
Well, I have spent last three hours reading a Java sychronization tutorial (a very good one) followed by more info about wait, notify and notifyAll, and i ended up with program that uses N threads to count from A to B, set N to 2 and you have odd and even.
pastebin
Also, my program has no comments whatsoever, so make sure you read the tutorial(s) before you try understand this code.
Also it never prints "Exit Main Thread".
That is because maybe because your threads are waiting on the lock for someone to notify() but due to missed signal or no one signalling them, they never get out of waiting state. For that the best solution is to use:
public final void wait(long timeout)
throws InterruptedException
Causes the current thread to wait until either another thread invokes
the notify() method or the notifyAll() method for this object, or a
specified amount of time has elapsed.
This overloaded method will wait for other thread to notify for specific amount of time and then return if timeout occurs. So in case of a missed signal the thread will still resume its work.
NOTE: After returning from wait state always check for
PRE-CONDITION again, as it can be a Spurious Wakeup.
Here is my flavor of program that I coded some time back for the same.
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
private static int range = 10;
private static volatile AtomicInteger present = new AtomicInteger(0);
private static Object lock = new Object();
public static void main(String[] args) {
new Thread(new OddRunnable()).start();
new Thread(new EvenRunnable()).start();
}
static class OddRunnable implements Runnable{
#Override
public void run() {
while(present.get() <= range){
if((present.get() % 2) != 0){
System.out.println(present.get());
present.incrementAndGet();
synchronized (lock) {
lock.notifyAll();
}
}else{
synchronized (lock) {
try {
lock.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
}
}
static class EvenRunnable implements Runnable{
#Override
public void run() {
while(present.get() <= range){
if((present.get() % 2) == 0){
System.out.println(present.get());
present.incrementAndGet();
synchronized (lock) {
lock.notifyAll();
}
}else{
synchronized (lock) {
try {
lock.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
}
}
}
See the solution, I have kept a lock that works for notifying the chance of even or odd thread. If even thread finds that the present number is not even it waits on the lock and
hopes that odd thread will notify it when it prints that odd number. And similarly it works for odd thread too.
I am not suggesting that this is the best solution but this is something that came out in the first try, some other options are also possible.
Also I would like to point out that this question though as a practice is good, but do keep in mind that you are not doing anything parallel there.
This could be an exercise on threads and lock monitors, but there is nothing to do in parallel that give you advantages.
In your code when a thread 1 (OddThread or EvenThread) ends his work and prints out "Odd Thread Finish" (or "Even Thread Finish") the other thread 2 is waiting a notify() or a notifyAll() that never will happen because the first is over.
You have to change EvenThread and OddThread adding a synchronized block with a notify call on commShare just after the while cycle. I removed the second if-branch because in this way you don't continue to check the while condition but get a wait on commShare soon.
class EvenThread implements Runnable {
private Share commShare;
private int number = 2;
public EvenThread(Share obj) {
this.commShare = obj;
}
public void run() {
System.out.println("Even Thread start");
while (number <= 50) {
synchronized (commShare) {
if (commShare.flag) {
System.out.println("Even Thread:" + number);
number += 2;
commShare.flag = false;
}
commShare.notify();
try {
commShare.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized (commShare) {
commShare.notify();
System.out.println("Even Thread Finish");
}
}
}
class OddThread implements Runnable {
private int number = 1;
private Share commShare;
public OddThread(Share obj) {
this.commShare = obj;
}
public void run() {
System.out.println("Odd Thread start");
while (number <= 50) {
synchronized (commShare) {
if (!commShare.flag) {
System.out.println("Odd Thread: " + number);
number += 2;
commShare.flag = true;
}
commShare.notify();
try {
commShare.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized (commShare) {
commShare.notify();
System.out.println("Odd Thread Finish");
}
}
Finally, in the main you have to join for each thread you started. It's sure that Thread.currentThread() returns just one of yours threads? We have started two threads and those threads we should join.
try {
even.join();
odd.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I will not vote for using wait() and notify(). The things that you can do with wait and notify can be done through more sophisticated tools like semaphore, countDownLatch, CyclicBarrier. You can find this advice in the famous book Effective java in item number 69 prefer concurrency utilities to wait and notify.
Even in this case we don't need this things at all, we can achieve this functionality by a simple volatile boolean variable. And for stopping a thread the best possible way is to use interrupt. After certain amount of time or some predefined condition we can interrupt threads. Please find my implementation attached:
Thread 1 for printing even numbers:
public class MyRunnable1 implements Runnable
{
public static volatile boolean isRun = false;
private int k = 0 ;
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
if(isRun){
System.out.println(k);
k+=2;
isRun=false;
MyRunnable2.isRun=true;
}
}
}
}
Thread 2 for printing even numbers:
public class MyRunnable2 implements Runnable{
public static volatile boolean isRun = false;
private int k = 1 ;
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
if(isRun){
System.out.println(k);
k+=2;
isRun=false;
MyRunnable1.isRun=true;
}
}
}
}
Now main method which drives the above threads
public class MyMain{
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(new MyRunnable1());
Thread t2 = new Thread(new MyRunnable2());
MyRunnable1.isRun=true;
t1.start();
t2.start();
Thread.currentThread().sleep(1000);
t1.interrupt();
t2.interrupt();
}
}
There may be some places you need to change a bit this is just a skeletal implementation. Hope it helps and please let me know if you need something else.
public class PrintNumbers {
public static class Condition {
private boolean start = false;
public boolean getStart() {
return start;
}
public void setStart(boolean start) {
this.start = start;
}
}
public static void main(String[] args) {
final Object lock = new Object();
// condition used to start the odd number thread first
final Condition condition = new Condition();
Thread oddThread = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
for (int i = 1; i <= 10; i = i + 2) { //For simplicity assume only printing till 10;
System.out.println(i);
//update condition value to signify that odd number thread has printed first
if (condition.getStart() == false) {
condition.setStart(true);
}
lock.notify();
try {
if (i + 2 <= 10) {
lock.wait(); //if more numbers to print, wait;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread evenThread = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
for (int i = 2; i <= 10; i = i + 2) { //For simplicity assume only printing till 10;
// if thread with odd number has not printed first, then wait
while (condition.getStart() == false) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
lock.notify();
try {
if (i + 2 <= 10) { //if more numbers to print, wait;
lock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
oddThread.start();
evenThread.start();
}
}
I did it using ReentrantLock with 25 threads . One thread Print One number and it will notify to other .
public class ReentrantLockHolder
{
private Lock lock;
private Condition condition;
public ReentrantLockHolder(Lock lock )
{
this.lock=lock;
this.condition=this.lock.newCondition();
}
public Lock getLock() {
return lock;
}
public void setLock(Lock lock) {
this.lock = lock;
}
public Condition getCondition() {
return condition;
}
public void setCondition(Condition condition) {
this.condition = condition;
}
}
public class PrintThreadUsingReentrantLock implements Runnable
{
private ReentrantLockHolder currHolder;
private ReentrantLockHolder nextHolder;
private PrintWriter writer;
private static int i=0;
public PrintThreadUsingReentrantLock(ReentrantLockHolder currHolder, ReentrantLockHolder nextHolder ,PrintWriter writer)
{
this.currHolder=currHolder;
this.nextHolder=nextHolder;
this.writer=writer;
}
#Override
public void run()
{
while (true)
{
writer.println(Thread.currentThread().getName()+ " "+ ++i);
try{
nextHolder.getLock().lock();
nextHolder.getCondition().signal();
}finally{
nextHolder.getLock().unlock();
}
try {
currHolder.getLock().lock();
currHolder.getCondition().await();
}catch (InterruptedException e)
{
e.printStackTrace();
}
finally{
currHolder.getLock().unlock();
}
}
}
}
public static void main(String[] args)
{
PrintWriter printWriter =null;
try {
printWriter=new PrintWriter(new FileOutputStream(new File("D://myFile.txt")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ReentrantLockHolder obj[]=new ReentrantLockHolder[25];
for(int i=0;i<25;i++)
{
obj[i]=new ReentrantLockHolder(new ReentrantLock());
}
for(int i=0;i<25;i++)
{
Thread t1=new Thread(new PrintThreadUsingReentrantLock(obj[i], obj[i+1 == 25 ? 0 : i+1],printWriter ),"T"+i );
t1.start();
}
}
I tried the similar stuff where Thread 1 prints Odd numbers and Thread 2 prints even numbers in a correct order and also when the printing is over, the desired messages as you had suggested will be printed. Please have a look at this code
package practice;
class Test {
private static boolean oddFlag = true;
int count = 1;
private void oddPrinter() {
synchronized (this) {
while(true) {
try {
if(count < 10) {
if(oddFlag) {
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + ": " + count++);
oddFlag = !oddFlag;
notifyAll();
}
else {
wait();
}
}
else {
System.out.println("Odd Thread finished");
notify();
break;
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void evenPrinter() {
synchronized (this) {
while (true) {
try {
if(count < 10) {
if(!oddFlag) {
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + ": " + count++);
oddFlag = !oddFlag;
notify();
}
else {
wait();
}
}
else {
System.out.println("Even Thread finished");
notify();
break;
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException{
final Test test = new Test();
Thread t1 = new Thread(new Runnable() {
public void run() {
test.oddPrinter();
}
}, "Thread 1");
Thread t2 = new Thread(new Runnable() {
public void run() {
test.evenPrinter();
}
}, "Thread 2");
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Main thread finished");
}
}
package test;
public class Interview2 {
public static void main(String[] args) {
Obj obj = new Obj();
Runnable evenThread = ()-> {
synchronized (obj) {
for(int i=2;i<=50;i+=2) {
while(!obj.printEven) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
obj.printEven = false;
obj.notify();
}
}
};
Runnable oddThread = ()-> {
synchronized (obj) {
for(int i=1;i<=49;i+=2) {
while(obj.printEven) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
obj.printEven = true;
obj.notify();
}
}
};
new Thread(evenThread).start();
new Thread(oddThread).start();
}
}
class Obj {
boolean printEven;
}
This is very generic solution. It uses semaphores to do signaling among threads.
This is general solution where N threads prints M natural numbers in sequence turn by turn.
that is if we have 3 threads and we want to print 7 natural numbers, output would be:
Thread 1 : 1
Thread 2 : 2
Thread 3 : 3
Thread 1 : 4
Thread 2 : 5
Thread 3 : 6
Thread 1 : 7
import java.util.concurrent.Semaphore;
/*
* Logic is based on simple idea
* each thread should wait for previous thread and then notify next thread in circular fashion
* There is no locking required
* Semaphores will do the signaling work among threads.
*/
public class NThreadsMNaturalNumbers {
private static volatile int nextNumberToPrint = 1;
private static int MaxNumberToPrint;
public static void main(String[] args) {
int numberOfThreads = 2;
MaxNumberToPrint = 50;
Semaphore s[] = new Semaphore[numberOfThreads];
// initialize Semaphores
for (int i = 0; i < numberOfThreads; i++) {
s[i] = new Semaphore(0);
}
// Create threads and initialize which thread they wait for and notify to
for (int i = 1; i <= numberOfThreads; i++) {
new Thread(new NumberPrinter("Thread " + i, s[i - 1], s[i % numberOfThreads])).start();
}
s[0].release();// So that First Thread can start Processing
}
private static class NumberPrinter implements Runnable {
private final Semaphore waitFor;
private final Semaphore notifyTo;
private final String name;
public NumberPrinter(String name, Semaphore waitFor, Semaphore notifyTo) {
this.waitFor = waitFor;
this.notifyTo = notifyTo;
this.name = name;
}
#Override
public void run() {
while (NThreadsMNaturalNumbers.nextNumberToPrint <= NThreadsMNaturalNumbers.MaxNumberToPrint) {
waitFor.acquireUninterruptibly();
if (NThreadsMNaturalNumbers.nextNumberToPrint <= NThreadsMNaturalNumbers.MaxNumberToPrint) {
System.out.println(name + " : " + NThreadsMNaturalNumbers.nextNumberToPrint++);
notifyTo.release();
}
}
notifyTo.release();
}
}
}
This Class prints Even Number:
public class EvenThreadDetails extends Thread{
int countNumber;
public EvenThreadDetails(int countNumber) {
this.countNumber=countNumber;
}
#Override
public void run()
{
for (int i = 0; i < countNumber; i++) {
if(i%2==0)
{
System.out.println("Even Number :"+i);
}
try {
Thread.sleep(2);
} catch (InterruptedException ex) {
// code to resume or terminate...
}
}
}
}
This Class prints Odd Numbers:
public class OddThreadDetails extends Thread {
int countNumber;
public OddThreadDetails(int countNumber) {
this.countNumber=countNumber;
}
#Override
public void run()
{
for (int i = 0; i < countNumber; i++) {
if(i%2!=0)
{
System.out.println("Odd Number :"+i);
}
try {
Thread.sleep(2);
} catch (InterruptedException ex) {
// code to resume or terminate...
}
}
}
}
This is Main class:
public class EvenOddDemo {
public static void main(String[] args) throws InterruptedException
{
Thread eventhread= new EvenThreadDetails(100);
Thread oddhread=new OddThreadDetails(100);
eventhread.start();
oddhread.start();
}
}
I have done it this way and its working...
class Printoddeven{
public synchronized void print(String msg){
try {
if(msg.equals("Even"))
{
for(int i=0;i<=10;i+=2){
System.out.println(msg+" "+i);
Thread.sleep(2000);
notify();
wait();
}
}
else{
for(int i=1;i<=10;i+=2){
System.out.println(msg+" "+i);
Thread.sleep(2000);
notify();
wait();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class PrintOdd extends Thread{
Printoddeven oddeven;
public PrintOdd(Printoddeven oddeven){
this.oddeven=oddeven;
}
public void run(){
oddeven.print("ODD");
}
}
class PrintEven extends Thread{
Printoddeven oddeven;
public PrintEven(Printoddeven oddeven){
this.oddeven=oddeven;
}
public void run(){
oddeven.print("Even");
}
}
public class mainclass
{
public static void main(String[] args)
{
Printoddeven obj = new Printoddeven();//only one object
PrintEven t1=new PrintEven(obj);
PrintOdd t2=new PrintOdd(obj);
t1.start();
t2.start();
}
}
public class Driver {
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
for (int itr = 1; itr < 51; itr = itr + 2) {
synchronized (lock) {
System.out.print(" " + itr);
try {
lock.notify();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("\nEven Thread Finish ");
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
for (int itr = 2; itr < 51; itr = itr + 2) {
synchronized (lock) {
System.out.print(" " + itr);
try {
lock.notify();
if(itr==50)
break;
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("\nOdd Thread Finish ");
}
});
try {
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Exit Main Thread");
} catch (Exception e) {
}
}
}
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();
}
}