Odd even number printing using thread

前端 未结 13 1957
挽巷
挽巷 2020-11-29 08:39

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.

相关标签:
13条回答
  • 2020-11-29 09:28

    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();
        }
    }
    
    0 讨论(0)
  • 2020-11-29 09:31

    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.

    0 讨论(0)
  • 2020-11-29 09:32

    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();
        }
    }
    
    0 讨论(0)
  • 2020-11-29 09:32

    You're missing volatile keyword within oddTurn variable. Without it there are no guarantees the threads see the actual value.

    0 讨论(0)
  • 2020-11-29 09:36

    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.

    0 讨论(0)
  • 2020-11-29 09:37

    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");
        }
    }
    
    0 讨论(0)
提交回复
热议问题