correct approach for 2 threads alternatively printing numbers - java

I have written a program which creates a 2 new thread and shares a common lock object to print numbers alternatively.
Wanted to know if the approach for using wait() and notify() is correct?
Main Class
public class MyMain {
public static void main(String[] args) {
MyThread1 obj = new MyThread1();
Thread thread1 = new Thread(obj);
Thread thread2 = new Thread(obj);
thread1.setName("t1");
thread2.setName("t2");
thread1.start();
thread2.start();
}
}
Thread Class
public class MyThread1 implements Runnable{
int i = 0;
#Override
public synchronized void run() {
while(i<10)
{
if(i%2==0)
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}else
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}
}
}
}
Can there be a better usage of wait() and notify() instead of using it in both the if conditions?

Since there you have some code repetition I'd just go with something like:
while(true) {
//If it's not my turn I'll wait.
if(i%2==0) wait();
// If I've reached this point is because:
// 1 it was my turn OR 2 someone waked me up (because it's my turn)
System.out.println(Thread.currentThread()": "+i);
i++; // Now is the other thread's turn
// So we wake him up
notify();
}
Also, be very careful with monitor's behaviour. (Thread waiting/notifying queues).

Related

Java Threads: How to print alphabets and numbers using two threads one at a time

I am trying to work around with threads in java. Though I understand that threads output are unpredictable, However was wondering if there is a way to do that.
I have to implement two threads, one prints alphabets(a,b,c...z) and other prints numbers(1,2,3....26). Have to implement it in such a way that the output should be a,1,b,2,c,3,d,4......z,26. Below is my code but it doesn't give the desired output.
public class ThreadsExample {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
System.out.print(i+",");
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
System.out.print(i+",");
}
}
}
What tweak should I make in the code to get the desired output? How does synchronization helps here? Or is it really possible when working with Threads at all?
PS: This is not an assignment or some exercise. Its self learning.
It is possible. You need to synchronize it well.
Approach Pseudocode
query some (synchronized) state
state will tell whether nums or chars are allowed
if state allows char and caller will put chars, do it now and change state and wake up waiting threads
if not, wait
if state allows numbers and caller will put numbers, do it now and change state and wake up waiting threads
if not, wait
Java code
public class ThreadsExample {
public static ThreadsExample output = new ThreadsExample ();
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
private Object syncher = new Object (); // we use an explicit synch Object, you could use annotation on methods, too. like ABHISHEK did.
// explicit allows to deal with more complex situations, especially you could have more the one locking Object
private int state = 0; // 0 allows chars, 1 allows ints
public void print (char pChar) {
synchronized (syncher) { // prevent the other print to access state
while (true) {
if (state == 0) { // char are allowed
System.out.print(pChar + ","); // print it
state = 1; // now allow ints
syncher.notify(); // wake up all waiting threads
return;
} else { // not allowed for now
try {
syncher.wait(); // wait on wake up
} catch (InterruptedException e) {
}
}
}
}
}
public void print (int pInt) {
synchronized (syncher) {
while (true) {
if (state == 1) {
System.out.print(pInt + ",");
state = 0;
syncher.notify();
return;
} else {
try {
syncher.wait();
} catch (InterruptedException e) {
}
}
}
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
ThreadsExample.output.print(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
ThreadsExample.output.print(i);
}
}
}
Output
a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i,9,j,10,k,11,l,12,m,13,n,14,o,15,p,16,q,17,r,18,s,19,t,20,u,21,v,22,w,23,x,24,y,25,z,26,
The whole idea of threads: it represents a "stream of activity" that executes code independent of other threads.
In your case, you want that these two threads go in "lockstep". Thread A does one step, then Thread B, then A, then B.
In order to get there, the two threads need something "synchronize" on - in other words: A sends a signal to B when it has done its steps - and B has to wait for that signal. Then B does its thing, signals to A, ...
For starters, a simple boolean value would do. One thread sets it to true, the other to false (to indicate when it has made its step). Then the thread waits for the boolean to toggle again.
As you intend to learn things, I would just start experimenting from there. In case you want to take detours, look here for example. This might help as well.
HERE IS THE CODE::
You need to create 2 threads and implement wait and notify methods correctly you can also refer "Create two threads, one display odd & other even numbers" for your answer.
public class ThreadClass {
volatile int i = 1;
volatile Character c = 'a';
volatile boolean state = true;
synchronized public void printAlphabet() {
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " +c);
state = false;
c++;
notifyAll();
}
synchronized public void printNumbers() {
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
state = true;
i++;
notifyAll();
}
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread() {
int k = 0;
#Override
public void run() {
while (k < 26) {
threadClass.printAlphabet();
k++;
}
}
};
t1.setName("Thread1");
Thread t2 = new Thread() {
int j = 0;
#Override
public void run() {
while (j < 26) {
threadClass.printNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Your threads are running at the same time. But not the way you want it, as mentioned above. You will see blocks of data from thread 1 and then a block of data from thread 2; and this is because of thread scheduling. Thread 1 is just queuing its output before thread 2.
To test this theory, increase your output to a 1000 records for example as the alphabet and 26 numbers are not as large to see this.
By doing so, you will see these 'blocks' of data. There is a way to do what you mentioned, but it is not advisable as this is not demonstrating how threads actually work but rather you forcing it to work that way.
With less Code:
class MyRunnable implements Runnable {
private static int n = 1;
private static char c = 'a';
public void run() {
for (int i = 1; i <= 26; i++) {
synchronized (this) {
try {
notifyAll();
if (Thread.currentThread().getName().equals("A")) {
System.out.print(c + ",");
c++;
} else {
System.out.print(n + ",");
n++;
}
if (i != 26) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintAlphabetNumberJob {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread tAlphabet = new Thread(r, "A");
Thread tNumber = new Thread(r, "N");
tAlphabet.start();
Thread.sleep(100);
tNumber.start();
}
}

Make one thread wait for another to finish

I have two thread classes: one that prints numbers from 0 to 9, and another from 100 to 109. What I want is to make the first thread wait for the other one to finish. For this, I used the join() method, but it's not working. Please tell me where I'm going wrong:
//demonstrates the use of join() to wait for another thread to finish
class AThread implements Runnable {
Thread t;
AThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=0; i<10; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
public void halt(Thread th) {
try {
th.join();
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
//a different thread class (we distinguish threads by their output)
class BThread implements Runnable {
Thread t;
BThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=100; i<110; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
public class WaitForThread {
public static void main(String[] args) {
AThread t1 = new AThread();
BThread t2 = new BThread();
t1.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
t2.t.start();
}
}
You call join on the thread before it has started. That doesn't work; in that case, join will return immediately, it's not going to wait until the other thread has started and stopped later. You can see this in the API documentation:
Thread.join()
This implementation uses a loop of this.wait calls conditioned on this.isAlive.
Thread.isAlive()
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
Reorder the statements in your main method
t1.t.start();
t2.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
edit to answer your questions in the comments:
If you want the thread in AThread to wait for the thread in BThread to finish before doing its job, then you'll need to call join in AThread.run, and change your main method:
class AThread implements Runnable {
Thread t;
Thread threadToWaitFor;
AThread(Thread threadToWaitFor) {
t = new Thread(this);
this.threadToWaitFor = threadToWaitFor;
}
public void run() {
// First wait for the other thread to finish
threadToWaitFor.join();
// ...
}
// ...
}
public class WaitForThread {
public static void main(String[] args) {
BThread t2 = new BThread();
AThread t1 = new AThread(t2.t);
t2.t.start();
t1.t.start();
}
}

Notify not getting the thread out of wait state

I am trying to use 2 threads. 1 thread prints only odd number and the other thread prints only even number and It has to be an alternative operation.
Eg:
Thread1 1
Thread2 2
Thread1 3
Thread2 4
and so on..
Below is the program, please let me know where I am going wrong as the thread1 is not coming out of wait state even when the thread2 is notifying it..
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (t) {
try {
t.notify();
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
Problem is that in one case you are taking lock on Thread t [synchronized (t) ] while in other case you are taking lock on TheadA object itself [synchronized(this)].
If you want threads to talk to each other then both should take lock on same object only then wait notify will work as you expect.
Edit:
There is another problem in your program, you are not using any variable to coordinate between 2 threads. SO you may see output like this 2,1,4,3...so on. Point is threads will work alternately but not in sequence.
So you should share a single variable between 2 threads which should be incremented.
Second issue is you are not taking care of spurious wake up calls [read some docs on this], you should always have wait called inside a while loop.
Modified my code based on the answer provided by Lokesh
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (ta) {
try {
ta.notify();
ta.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
You have a real confusion of threads and locks. I suggest you create one and only one object to use for locking to start with as you don't appear to have a clear idea what you are locking.
If you notify() and nothing is listening, the signal is lost. However, a wait() can wake spuriously.
For this reason, a notify() should be accompanied by a state change and a wait() should be in a loop checking that change.

What if I am waiting on an object which is not Runnable?

Consider the following code :-
public class UsingWait1{
public static void main(String... aaa){
CalculateSeries r = new CalculateSeries();
Thread t = new Thread(r);
t.start();
synchronized(r){
try{
r.wait(); //Here I am waiting on an object which is Runnable. So from its run method, it can notify me (from inside a synchronized block).
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
System.out.println(r.total);
try{
Thread.sleep(1);
} catch (InterruptedException e){
System.out.println("Interrupted");
}
System.out.println(r.total);
}
}
class CalculateSeries implements Runnable{
int total;
public void run(){
synchronized(this){
for(int i = 1; i <= 10000; i++){
total += i;
}
notify(); // Line 1 .. Notify Exactly one of all the threads waiting on this instance of the class to wake up
}
}
}
Here I am waiting on CalculateSeries which is Runnable. So I can notify the waiting thread from the run() method of CalculateSeries.
But now, consider the following code where I am waiting on an object which is not Runnable.
public class WaitNotOnThread{
public static void main(String... aaa){
NotRunnable nr = new NotRunnable();
IAmRunnable r = new IAmRunnable(nr);
new Thread(r).start();
synchronized(nr){
try{
nr.wait();
} catch(InterruptedException e){
System.out.println("Wait interrupted");
}
System.out.println("After being notified within synchronized");
}
System.out.println("After synchronized");
}
}
class IAmRunnable implements Runnable{
NotRunnable nr;
IAmRunnable(NotRunnable nr){
this.nr = nr;
}
public void run(){
synchronized(nr){
try{
Thread.sleep(1000);
} catch(InterruptedException e){
System.out.println("Sleeping Interrupted :( ");
}
notify(); // Line 2
}
}
}
class NotRunnable{
}
Here I get an IllegalMonitorStateException at Line 2. I am waiting on the same instance of the object (which is not Runnable) while calling both, wait() as well as notify(). Then what is the problem?
Can someone also give some scenarios where it would be useful to wait on an object which is not Runnable??
Wait need not be on Runnable. That is why notify() is on Object and not on Runnable. I guess that helps in all cases we want to avoid busy wait.
The problem seems to be the synchronized() is on nr, and the notify is called on different object. Also synchronized should be on final variables.
class IAmRunnable implements Runnable {
final NotRunnable nr;
IAmRunnable( final NotRunnable nr) {
this.nr = nr;
}
public void run() {
synchronized (nr) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Sleeping Interrupted :( ");
}
nr.notify(); // Line 2
}
}
}

How to make a thread wait and execute another???

I have two Threads classes "AddThread" and "ReadThread". The execution of these threads should be like this "AddThread should add 1 record and wait until ReadThread displays the record after that ReadThread should display that added record again AddThread should add another record" this process should continue untill all the records are added(REcords are accessed from LinkedList). Here is the code
class AddThread extends Thread
{
private Xml_Parse xParse;
LinkedList commonlist;
AddThread(LinkedList commonEmpList)
{
commonlist = commonEmpList;
}
public void run()
{
System.out.println("RUN");
xParse=new Xml_Parse();
LinkedList newList=xParse.xmlParse();
try
{
synchronized (this) {
if(newList.size()>0)
{
for(int i=0;i<newList.size();i++)
{
System.out.println("FOR");
commonlist.add(newList.get(i));
System.out.println("Added" +(i+1)+ "Record");
}
System.out.println(commonlist.size());
}
}
}
catch(Exception e)
{
}
}
}
class ReadThread extends Thread
{
LinkedList commonlist;
ReadThread(LinkedList commonEmpList)
{
commonlist = commonEmpList;
}
public void run()
{
try
{
synchronized (this) {
System.out.println();
System.out.println("ReadThread RUN");
sleep(1000);
//System.out.println("After waiting ReadThread RUN");
System.out.println(commonlist.size());
if(commonlist.size()>0)
{
for(int j=0;j<commonlist.size();j++)
{
System.out.println("Read For");
System.out.println("EmpNo: "+((EmployeeList)commonlist.get(j)).getEmpno());
System.out.println("EmpName: "+((EmployeeList)commonlist.get(j)).getEname());
System.out.println("EmpSal: "+((EmployeeList)commonlist.get(j)).getEmpsal());
}
}
}
}
catch(Exception e)
{
}
}
}
public class MainThread
{
public static LinkedList commonlist=new LinkedList();
public static void main(String args[])
{
AddThread addThread=new AddThread(commonlist);
ReadThread readThread=new ReadThread(commonlist);
addThread.start();
readThread.start();
}
}
You'll need to learn how to effectively use wait() and notify().
See also:
Guarded Blocks
What about using a BlockingQueue with a capacity of 1? Use offer instead of add so that producer thread is blocked.
You might also consider using a Semaphore with one permit, making it a mutex.
You use join() and yield() to control flux. If you want the current thread to stop and wait until the new thread finishes the work,
t1.run()
t.join()
when t1 finishes t continues.

Categories