Printing Even and Odd using two Threads in Java

Found the solution. Someone looking for solution to this problem can refer :-)

public class PrintEvenOddTester {

    public static void main(String... args) {
        Printer print = new Printer();
        Thread t1 = new Thread(new TaskEvenOdd(print, 10, false));
        Thread t2 = new Thread(new TaskEvenOdd(print, 10, true));
        t1.start();
        t2.start();
    }

}

class TaskEvenOdd implements Runnable {

    private int max;
    private Printer print;
    private boolean isEvenNumber;

    TaskEvenOdd(Printer print, int max, boolean isEvenNumber) {
        this.print = print;
        this.max = max;
        this.isEvenNumber = isEvenNumber;
    }

    @Override
    public void run() {

        //System.out.println("Run method");
        int number = isEvenNumber == true ? 2 : 1;
        while (number <= max) {

            if (isEvenNumber) {
                //System.out.println("Even :"+ Thread.currentThread().getName());
                print.printEven(number);
                //number+=2;
            } else {
                //System.out.println("Odd :"+ Thread.currentThread().getName());
                print.printOdd(number);
                // number+=2;
            }
            number += 2;
        }

    }

}

class Printer {

    boolean isOdd = false;

    synchronized void printEven(int number) {

        while (isOdd == false) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Even:" + number);
        isOdd = false;
        notifyAll();
    }

    synchronized void printOdd(int number) {
        while (isOdd == true) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Odd:" + number);
        isOdd = true;
        notifyAll();
    }

}

This gives output like:

Odd:1
Even:2
Odd:3
Even:4
Odd:5
Even:6
Odd:7
Even:8
Odd:9
Even:10

   private Object lock = new Object();
   private volatile boolean isOdd = false;


    public void generateEvenNumbers(int number) throws InterruptedException {

        synchronized (lock) {
            while (isOdd == false) 
            {
                lock.wait();
            }
            System.out.println(number);
            isOdd = false;
            lock.notifyAll();
        }
    }

    public void generateOddNumbers(int number) throws InterruptedException {

        synchronized (lock) {
            while (isOdd == true) {
                lock.wait();
            }
            System.out.println(number);
            isOdd = true;
            lock.notifyAll();
        }
    }

Use this following very simple JAVA 8 Runnable Class feature

public class MultiThreadExample {

static AtomicInteger atomicNumber = new AtomicInteger(1);

public static void main(String[] args) {
    Runnable print = () -> {
        while (atomicNumber.get() < 10) {
            synchronized (atomicNumber) {
                if ((atomicNumber.get() % 2 == 0) && "Even".equals(Thread.currentThread().getName())) {
                    System.out.println("Even" + ":" + atomicNumber.getAndIncrement());
                } //else if ((atomicNumber.get() % 2 != 0) && "Odd".equals(Thread.currentThread().getName()))
                   else {System.out.println("Odd" + ":" + atomicNumber.getAndIncrement());
                }
            }
        }
    };

    Thread t1 = new Thread(print);
    t1.setName("Even");
    t1.start();
    Thread t2 = new Thread(print);
    t2.setName("Odd");
    t2.start();

}
}

Here is the code which I made it work through a single class

package com.learn.thread;

public class PrintNumbers extends Thread {
volatile static int i = 1;
Object lock;

PrintNumbers(Object lock) {
    this.lock = lock;
}

public static void main(String ar[]) {
    Object obj = new Object();
    // This constructor is required for the identification of wait/notify
    // communication
    PrintNumbers odd = new PrintNumbers(obj);
    PrintNumbers even = new PrintNumbers(obj);
    odd.setName("Odd");
    even.setName("Even");
    odd.start();
    even.start();
}

@Override
public void run() {
    while (i <= 10) {
        if (i % 2 == 0 && Thread.currentThread().getName().equals("Even")) {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + " - "
                        + i);
                i++;
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        if (i % 2 == 1 && Thread.currentThread().getName().equals("Odd")) {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + " - "
                        + i);
                i++;
                lock.notify();
              }
           }
        }
    }
}

Output:

Odd - 1
Even - 2
Odd - 3
Even - 4
Odd - 5
Even - 6
Odd - 7
Even - 8
Odd - 9
Even - 10
Odd - 11