I wrote a Multithreaded program in Java given below :-
public class Client {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Counter counter = new Counter();
int val = counter.getValue();
while(val < 5){
val = counter.getValue();
System.out.println("In main thread : "+val);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Counter implements Runnable {
private int countValue;
Counter(){
countValue = 0;
Thread thread = new Thread(this ,"Counter A");
Thread thread1 = new Thread(this ,"Counter B");
thread.start();
thread1.start();
}
int getValue(){
return countValue;
}
#Override
public void run() {
// TODO Auto-generated method stub
while( countValue < 5){
System.out.println("In child thread : "+ ++countValue );
try {
Thread.sleep(250);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
and output of program is
output :-
In main thread : 0
In child thread : 2
In child thread : 1
In child thread : 3
In child thread : 3
In child thread : 4
In child thread : 5
In main thread : 5
Can anybody explain me in detail how this output came.Thank you in advance
You have 3 threads (main and 2 child) that are all running in parallel (unless you have a single proc box) that are all reading and writing a resource countValue that isn't protected by any kind of synchronization.
When you do things like this, you'll get apparently random output.
Related
This is my code
import java.util.concurrent.SynchronousQueue;
public class Mywork {
public static void main(String args[])
{
SynchronousQueue<String> s=new SynchronousQueue<>();
Producer1 p1 =new Producer1(s);
Producer2 p2=new Producer2(s);
new Thread(p1).start();
new Thread(p2).start();
}
}
class Producer1 implements Runnable
{
SynchronousQueue<String> s=null;
Producer1(SynchronousQueue<String> q)
{
this.s=q;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
s.put("Suman");
System.out.println(s);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//
class Producer2 implements Runnable
{
SynchronousQueue<String> s=null;
Producer2(SynchronousQueue<String> q)
{
this.s=q;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
s.put("Ghosh");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
whenever the put is performed after that I am not ale to debug it , the control vanishes from the eclipse
any idea why it is happening ?
From the doc:
The put method will block until another thread retrieved data from SynchronousQueue.
put(E o)
Adds the specified element to this queue, waiting if necessary for
another thread to receive it.
That said, SynchronousQueue will not return until there is a corresponding take() call. And, you are adding element in both thread and caused wait.
So, changing
s.put("Ghosh");
to
String str = s.take();
will continue execution.
I am trying to run below written program. But Here I am getting exception as
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at main.java.OddEven$even.run(OddEven.java:16)
at java.lang.Thread.run(Unknown Source)
I am unable to find reason behind exception.
Execption is occuring in notify method. We get IllegalMonitorStateException in notify method only when current thread does not own the lock object.
public class OddEven {
private Integer count = 0;
Object ob = new Object();
class even implements Runnable {
#Override
public void run() {
while (count % 2 == 0) {
synchronized (ob) {
if (count % 2 == 0) {
System.out.println(count++);
notify();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
class odd implements Runnable {
#Override
public void run() {
while (count % 2 != 0) {
synchronized (ob) {
if (count % 2 != 0) {
System.out.println(count++);
notify();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
public static void main(String[] args) throws CloneNotSupportedException {
OddEven t1 = new OddEven();
Thread e = new Thread(t1.new even());
Thread o = new Thread(t1.new odd());
e.start();
o.start();
}
}
To call notify() on an object you need to have a lock on that object, i.e. be in a block synchronized on that object. You are in a synchronized block, but you are synchronizing on ob, while you are calling notify()on this.
You either have to also use ob for your notify()and wait() calls, or synchronize on this.
i have a class FeatOrientation and in that class in its constructor i perform two operations each one in a separate thread and i am using CountDownLatch so that, when gaussThread finishes the laplaceThread startes.
and in the main class that has the main method i am using ExecutorService and in the
".runAsync(new FeatOrientRun(bgrMat), featOrientExe);"
in the run method i call "calcFeatOrient" function and in that function i instantiate an object
from the FeatOrientation class. and the line
"CompletableFuture.allOf(future0).join();"
i used it to block the main thread till the two threads in the FeatOrientation class finih and then i do some calculation or display some data as in
"Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());".
the problem is , at run time i receive the output shown below from the console despit the getSmoothedImgList is not empty. I knew that it is not empty by commenting out the following three lines:
featOrientExe = Executors.newFixedThreadPool(1);
future0 = CompletableFuture.runAsync(new FeatOrientRun(bgrMat), featOrientExe);
CompletableFuture.allOf(future0).join();//blocks the main thread till future0, and future1 finishes
featOrientExe.shutdown();
and i instantiated an object from the FeatOrientation class in the main method and then , made the main thread to sleep for 7 seconds and after the 7 seconds, i called the following lines
Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());
Log.D(TAG, "MainClass", "SubSampledImgList:" + fo.getSubSampledImgList().size());
for (int i = 0; i < fo.getSmoothedImgList().size(); i++) {
ImageUtils.showMat(fo.getSmoothedImgList().get(i), "SmoothedImgList_" + i);
}
for (int i = 0; i < fo.getSubSampledImgList().size(); i++) {
//Mat laplaceImg = SysUtils.applyLaplac(fo.getSubSampledImgList().get(i));
//ImageUtils.showMat(laplaceImg, "getSubSampledImgList" + i);
}
and i received outout.
please let ma know what i am doing wrong with the ExecutorService, and why the approach i am following in the below posted code does not work desoite i wait till the FeatOrientation class finish it works.
console out put:
1: Error: FeatOrientation -> getSmoothedImgList: smoothedImgList is empty
Exception in thread "main" java.lang.NullPointerException
at com.example.featorientation_00.MainClass.main(MainClass.java:39)
main class:
public static void main(String[] args) {
MatFactory matFactory = new MatFactory();
FilePathUtils.addInputPath(path_Obj);
Mat bgrMat = matFactory.newMat(FilePathUtils.getInputFileFullPathList().get(0));
featOrientExe = Executors.newFixedThreadPool(1);
future0 = CompletableFuture.runAsync(new FeatOrientRun(bgrMat), featOrientExe);
CompletableFuture.allOf(future0).join();//blocks the main thread till future0, and future1 finishes
featOrientExe.shutdown();
Log.D(TAG, "MainClass", "SmoothedImgList:" + fo.getSmoothedImgList().size());
Log.D(TAG, "MainClass", "SubSampledImgList:" + fo.getSubSampledImgList().size());
for (int i = 0; i < fo.getSmoothedImgList().size(); i++) {
ImageUtils.showMat(fo.getSmoothedImgList().get(i), "SmoothedImgList_" + i);
}
for (int i = 0; i < fo.getSubSampledImgList().size(); i++) {
//Mat laplaceImg = SysUtils.applyLaplac(fo.getSubSampledImgList().get(i));
//ImageUtils.showMat(laplaceImg, "getSubSampledImgList" + i);
}
}
static class FeatOrientRun implements Runnable {
private Mat bgrMat;
public FeatOrientRun(Mat bgrMat) {
// TODO Auto-generated constructor stub
this.bgrMat = bgrMat;
}
public void run() {
// TODO Auto-generated method stub
calcFeatOrient(this.bgrMat);
}
}
public static void calcFeatOrient(Mat bgrMat) {
// TODO Auto-generated method stub
fo = new FeatOrientation(bgrMat);
}
FeatOrientation class:
public FeatOrientation(Mat bgrMat) {
// TODO Auto-generated constructor stub
this.origBGRImgList = new ArrayList<Mat>();
this.origGSImgList = new ArrayList<Mat>();
this.smoothedImgList = new ArrayList<Mat>();
this.downSampledImgList = new ArrayList<Mat>();
this.laplaceImgList = new ArrayList<Mat>();
this.latch = new CountDownLatch(1);
if (bgrMat != null) {
if (!bgrMat.empty()) {
if (bgrMat.channels() == 3) {
if ( (bgrMat.size().width >= SysConsts.MIN_IMG_WIDTH) && (bgrMat.size().height >= SysConsts.MIN_IMG_HEIGHT) ) {
this.bgrMat = bgrMat;
this.gaussThread = new Thread(new GaussRun(this.bgrMat, this.latch), "GAUSSIAN_THREAD");
this.laplaceThread = new Thread(new LaplaceRun(this.latch), "GAUSSIAN_THREAD");
this.gaussThread.start();
this.laplaceThread.start();
} else {
Log.E(TAG, "FeatOrientation", "the Mat you passed to the constructor has size: " + this.bgrMat.size() +
" the minimum width must = " + SysConsts.MIN_IMG_WIDTH +
" and the maximum height must = " + SysConsts.MIN_IMG_HEIGHT);
}
} else {
Log.E(TAG, "FeatOrientation", "BGR mat passed to the constructor does not has 3 channels.");
}
} else {
Log.E(TAG, "FeatOrientation", "BGR mat passed to the constructor is empty");
}
} else {
Log.E(TAG, "FeatOrientation", "the BGR mat you passed to the constructor is null");
}
}
class GaussRun implements Runnable {
private Mat bgrMat;
private CountDownLatch latch;
public GaussRun(Mat bgrMat, CountDownLatch latch) {
// TODO Auto-generated constructor stub
this.bgrMat = bgrMat;
this.latch = latch;
}
public void run() {
// TODO Auto-generated method stub
applyGaussianPyr(this.bgrMat);
this.latch.countDown();
}
}
class LaplaceRun implements Runnable {
private CountDownLatch latch;
public LaplaceRun(CountDownLatch latch) {
// TODO Auto-generated constructor stub
this.latch = latch;
}
public void run() {
// TODO Auto-generated method stub
try {
this.latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
applyLaplacianPyr();
}
}
Your collection is not thread safe so while the task may have finished, this doesn't mean the result is visible to another thread.
You could use a thread safe collection, but I prefer to return the results via Future<List<X>> and call list = future.get() This will both wait for the result and ensure it is passed in a thread safe manner regardless of which collection you use.
I assume this is just an example.
Running threads only makes sense if you have independent tasks (plural) to perform. It makes no sense to start one thread and wait for it's response, you may as well do the work in the current thread as it will be simpler and faster.
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) {
}
}
}
I believe that the main thread cannot die before the child thread. But is there any way to check that ? I wrote a simple program below. Can anyone prove it practically leaving theory aside ?
class childre extends Thread
{
public void run()
{
for( int i=0 ; i<10 ;i++)
{
System.out.println( " child " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ChildThreadb4main
{
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
System.out.println("main");
childre c1 = new childre();
c1.start();
for(int i=0;i<5;i++)
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println( " child thread alive ? " + c1.isAlive());
}
}
After suggestion from James. I tried the following program.
public class MainChildDie {
public static void main(String ar[]){
final Thread mainThread = Thread.currentThread();
System.out.println("main run ");
new Thread(){
public void run(){
Thread childThread= Thread.currentThread();
for(int i=0; i<10;i++){
System.out.println( "child"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main alive " + mainThread.isAlive());
}
}.start();
}
}
From http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html :
The Java Virtual Machine continues to execute threads until either of
the following occurs:
The exit method of class Runtime has been called and the security
manager has permitted the exit operation to take place.
All threads
that are not daemon threads have died, either by returning from the
call to the run method or by throwing an exception that propagates
beyond the run method.
In your case, when the main thread dies, the JVM does not exit, because you still have the created threads running, and they're daemon by default, because of this:
The newly created thread is initially marked as being a daemon thread if and only if the thread creating it is currently marked as a daemon thread. The method setDaemon may be used to change whether or not a thread is a daemon.
Cite: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)
While the code is executing, take a Full Thread dump and see what all Threads are active.
class AnotherClass {
public static void main(String arrp[]) throws Exception {
Thread t = new Thread() {
public void run() {
while (true) {
// do nothing
}
}
};
t.start();
//Sleep for 15 seconds
Thread.sleep(15000);
}
}
Compile and Execute it:
$ javac AnotherClass.java
$ java AnotherClass
Find the process:
$ ps -ef | grep AnotherClass
nikunj <<10720>> 10681 2 12:01:02 pts/9 0:04 java AnotherClass
nikunj 10722 10693 0 12:01:05 pts/6 0:00 grep Another
Take the Thread dump:
$ kill -3 <<10720>>
Output (excerpts):
"main" prio=10 tid=0x00039330 nid=0x1 waiting on condition [0xffbfe000..0xffbfe2a8]
at java.lang.Thread.sleep(Native Method)
at AnotherClass.main(AnotherClass.java:12)
"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970]
at AnotherClass$1.run(AnotherClass.java:7)
Take Another Thread dump (after 15 seconds):
$ kill -3 <<10720>>
New Output (excerpts):
"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970]
at AnotherClass$1.run(AnotherClass.java:7)
Conclusion:
main is gone.
Thread.currentThread().getThreadGroup().activeCount()
will return the active threads of a threadgroup of current thread default main
class childre extends Thread
{
public void run()
{
for( int i=0 ; i<10 ;i++)
{
System.out.println( " child " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getThreadGroup().activeCount());
}
}
You can use 'join' method to make sure that main thread waits till the child thread is completed.
childre c1 = new childre();
c1.start();
try {
c1.join();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
class Print implements Runnable
{
Thread thread, mainThread;
Print(Thread t)
{
mainThread = t;
thread = new Thread(this, "Thread");
thread.start();
}
#Override
public void run()
{
for(int i = 0; i < 5; i++)
{
System.out.println(thread.getName() + "\t" + (i+1));
try
{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
System.out.println("Interrupted Exception " + thread.getName());
}
System.out.println("Is main thread alive "+mainThread.isAlive());
}
}
}
public class ThreadOne
{
public static void main(String[] args)
{
Print p1 = new Print(Thread.currentThread());
System.out.println("Main Thread Ends");
}
}
The above code will show you that the main thread has completed execution while the newThread spawned still running.