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

roger_that :

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.

stefan bachert :

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,

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=474848&siteId=1