Печать Even and Odd с использованием двух потоков в Java

Я попробовал код ниже. Я взял этот кусок кода из какой-то другой статьи, которая правильна в соответствии с автором. Но когда я пытаюсь работать, это не дает мне точного результата.

Это в основном для непрерывной печати четных и нечетных значений.

public class PrintEvenOddTester {



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


}



class TaskEvenOdd implements Runnable {

    int number=1;
    Printer print;

    TaskEvenOdd(Printer print){
        this.print = print;
    }

    @Override
    public void run() {

        System.out.println("Run method");
        while(number<10){

            if(number%2 == 0){
                System.out.println("Number is :"+ number);
                print.printEven(number);
                number+=2;
            }
            else {
                System.out.println("Number is :"+ number);
                print.printOdd(number);
                number+=2;
            }
        }

      }

    }

class Printer {

    boolean isOdd;

    Printer(boolean isOdd){
        this.isOdd = isOdd;
    }

    synchronized void printEven(int number) {

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

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

}

Может кто-нибудь помочь мне в исправлении этого?

ИЗМЕНИТЬ Ожидаемый результат: Odd: 1 Даже: 2 Нечетный: 3 Даже: 4 Странно: 5 Даже: 6 Странно: 7 Даже: 8 Нечетный: 9

Ответ 1

Нашел решение. Кто-то, кто ищет решение этой проблемы, может ссылаться: -)

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();
    }

}

Это дает результат, например:

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

Ответ 2

Вот код, который я заставил его работать через один класс

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();
              }
           }
        }
    }
}

Вывод:

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

Ответ 3

Используйте эту следующую очень простую функцию JAVA 8 Runnable Class

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())) {
                    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();

}
}

Ответ 4

Эта программа может быть написана в два ways-

  • Использование ожидания и уведомления для связи между потоками. Но недостатком этого является то, что если количество потоков увеличивается более двух, то оно не может быть использовано.
  • Использование Java Semaphore для взаимодействия между потоками. Это более расширяемое и может быть изменено, даже если вопрос будет дополнительно изменен примерно на 3 темы -

пакет com.effectivecorejava; import java.util.concurrent.Semaphore;

public class SemaphoreExample {

public static void main(String[] args) {

    //We dont want the even number printed first so the initial permit for this semaphore is 0.
    Semaphore evenSemaphore = new Semaphore(0);
    //We want to print the odd number first so the initial permit for this semaphore is 1.
    Semaphore oddSemaphore = new Semaphore(1);

    PrintOddNumber printOddNumber = new PrintOddNumber(evenSemaphore, oddSemaphore);
    PrintEvenNumber printEvenNumber = new PrintEvenNumber(evenSemaphore, oddSemaphore);

    new Thread(printOddNumber, "Print Odd").start();
    new Thread(printEvenNumber, "Print Odd").start();
}

}

class PrintEvenNumber implements Runnable {

Semaphore sempahoreEven;
Semaphore sempahoreOdd;

public PrintEvenNumber(Semaphore sempahoreEven, Semaphore sempahoreOdd) {
    super();
    this.sempahoreEven = sempahoreEven;
    this.sempahoreOdd = sempahoreOdd;
}

@Override
public void run() {
    for (int i = 2;; i = i + 2) {
        try {
            //This will decrement the permit used by the even semaphore to 0. 
            sempahoreEven.acquire();
            System.out.println(i);
            //This will increment the permit used by odd semaphore by 1.
            sempahoreOdd.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

}

class PrintOddNumber implements Runnable {

Semaphore sempahoreEven;
Semaphore sempahoreOdd;

public PrintOddNumber(Semaphore sempahoreEven, Semaphore sempahoreOdd) {
    this.sempahoreEven = sempahoreEven;
    this.sempahoreOdd = sempahoreOdd;
}

@Override
public void run() {
    for (int i = 1;; i = i + 2) {
        try {
            //This will decrement the permit used by the odd semaphore to 0. 
            sempahoreOdd.acquire();

            Thread.sleep(1000);
            System.out.println(i);
            //This will increment the permit used by even semaphore by 1.
            sempahoreEven.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

}

Ответ 5

   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();
        }
    }

Ответ 6

Этот код также будет работать нормально.

class Thread1 implements Runnable {

    private static boolean evenFlag = true;

    public synchronized void run() {
        if (evenFlag == true) {
            printEven();
        } else {
           printOdd();
        }
    }

    public void printEven() {
        for (int i = 0; i <= 10; i += 2) {
            System.out.println(i+""+Thread.currentThread());
        }
        evenFlag = false;
    }

    public  void printOdd() {
        for (int i = 1; i <= 11; i += 2) {
            System.out.println(i+""+Thread.currentThread());
        }
        evenFlag = true;
    }
}

public class OddEvenDemo {

    public static void main(String[] args) {

        Thread1 t1 = new Thread1();
        Thread td1 = new Thread(t1);
        Thread td2 = new Thread(t1);
        td1.start();
        td2.start();

    }
}

Ответ 7

То же самое можно сделать с интерфейсом Lock:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class NumberPrinter implements Runnable {
    private Lock lock;
    private Condition condition;
    private String type;
    private static boolean oddTurn = true;

    public NumberPrinter(String type, Lock lock, Condition condition) {
        this.type = type;
        this.lock = lock;
        this.condition = condition;
    }

    public void run() {
        int i = type.equals("odd") ? 1 : 2;
        while (i <= 10) {
            if (type.equals("odd"))
                printOdd(i);
            if (type.equals("even"))
                printEven(i);
            i = i + 2;
        }
    }

    private void printOdd(int i) {
        // synchronized (lock) {
        lock.lock();
        while (!oddTurn) {
            try {
                // lock.wait();
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(type + " " + i);
        oddTurn = false;
        // lock.notifyAll();
        condition.signalAll();
        lock.unlock();
    }

    // }

    private void printEven(int i) {
        // synchronized (lock) {
        lock.lock();
        while (oddTurn) {
            try {
                // lock.wait();
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(type + " " + i);
        oddTurn = true;
        // lock.notifyAll();
        condition.signalAll();
        lock.unlock();
    }

    // }

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        Thread odd = new Thread(new NumberPrinter("odd", lock, condition));
        Thread even = new Thread(new NumberPrinter("even", lock, condition));
        odd.start();
        even.start();
    }
}

Ответ 8

Это самое простое решение для этой проблемы.

public class OddEven implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub

        for (int i = 1; i <= 10; i++) {
            synchronized (this) {
                if (i % 2 == 0 && Thread.currentThread().getName().equals("t2")) {
                    try {
                        notifyAll();
                        System.out.println("Even Thread : " + i);
                        wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } else if (i % 2 != 0
                        && Thread.currentThread().getName().equals("t1")) {
                    try {
                        notifyAll();
                        System.out.println("Odd Thread : " + i);
                        wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }

    }

    public static void main(String[] args) {

        OddEven obj = new OddEven();
        Thread t1 = new Thread(obj, "t1");
        Thread t2 = new Thread(obj, "t2");
        t1.start();
        t2.start();

    }
}

Ответ 9

import java.util.concurrent.atomic.AtomicInteger;


public class PrintEvenOddTester {
      public static void main(String ... args){
            Printer print = new Printer(false);
            Thread t1 = new Thread(new TaskEvenOdd(print, "Thread1", new AtomicInteger(1)));
            Thread t2 = new Thread(new TaskEvenOdd(print,"Thread2" , new AtomicInteger(2)));
            t1.start();
            t2.start();
        }
}

class TaskEvenOdd implements Runnable {
    Printer print;
    String name;
    AtomicInteger number;
    TaskEvenOdd(Printer print, String name, AtomicInteger number){
        this.print = print;
        this.name = name;
        this.number = number;
    }

    @Override
    public void run() {

        System.out.println("Run method");
        while(number.get()<10){

            if(number.get()%2 == 0){
                print.printEven(number.get(),name);
            }
            else {
                print.printOdd(number.get(),name);
            }
            number.addAndGet(2);
        }

      }

    }



class Printer {
    boolean isEven;

    public Printer() {  }

    public Printer(boolean isEven) {
        this.isEven = isEven;
    }

    synchronized void printEven(int number, String name) {

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

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

Ответ 10

Другой вопрос был закрыт как дубликат этого. Я думаю, что мы можем спокойно избавиться от "четной или нечетной" проблемы и использовать конструкцию wait/notify следующим образом:

public class WaitNotifyDemoEvenOddThreads {
    /**
     * A transfer object, only use with proper client side locking!
     */
    static final class LastNumber {
        int num;
        final int limit;

        LastNumber(int num, int limit) {
            this.num = num;
            this.limit = limit;
        }
    }

    static final class NumberPrinter implements Runnable {
        private final LastNumber last;
        private final int init;

        NumberPrinter(LastNumber last, int init) {
            this.last = last;
            this.init = init;
        }

        @Override
        public void run() {
            int i = init;
            synchronized (last) {
                while (i <= last.limit) {
                    while (last.num != i) {
                        try {
                            last.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(Thread.currentThread().getName() + " prints: " + i);
                    last.num = i + 1;
                    i += 2;
                    last.notify();
                }
            }
        }
    }

    public static void main(String[] args) {
        LastNumber last = new LastNumber(0, 10); // or 0, 1000
        NumberPrinter odd = new NumberPrinter(last, 1);
        NumberPrinter even = new NumberPrinter(last, 0);
        new Thread(odd, "o").start();
        new Thread(even, "e").start();
    }
}

Ответ 11

Simpler Version in Java 8:

public class EvenOddPrinter {
    static boolean flag = true;
    public static void main(String[] args) {
        Runnable odd = () -> {
            for (int i = 1; i <= 10;) {
                if(EvenOddPrinter.flag) {
                    System.out.println(i);
                    i+=2;
                    EvenOddPrinter.flag = !EvenOddPrinter.flag;
                }
            }
        };

        Runnable even = () -> {
            for (int i = 2; i <= 10;) {
                if(!EvenOddPrinter.flag) {
                    System.out.println(i);
                    i+=2;
                    EvenOddPrinter.flag = !EvenOddPrinter.flag;
                }
            }
        };

         Thread t1 = new Thread(odd, "Odd");
         Thread t2 = new Thread(even, "Even");
         t1.start();
         t2.start();
    }
}

Ответ 12

package pkgscjp;

public class OddPrint implements Runnable {

    public static boolean flag = true;

    public void run() {
        for (int i = 1; i <= 99;) {
            if (flag) {
                System.out.println(i);
                flag = false;
                i = i + 2;
            }
        }
    }

}


package pkgscjp;

public class EvenPrint implements Runnable {
    public void run() {
        for (int i = 2; i <= 100;) {
            if (!OddPrint.flag) {
                System.out.println(i);
                OddPrint.flag = true;
                i = i + 2;
            }
        }

    }
}


package pkgscjp;

public class NaturalNumberThreadMain {
    public static void main(String args[]) {
        EvenPrint ep = new EvenPrint();
        OddPrint op = new OddPrint();
        Thread te = new Thread(ep);
        Thread to = new Thread(op);
        to.start();
        te.start();

    }

}

Ответ 13

Я сделал это таким образом, при печати с использованием двух потоков мы не можем предсказать последовательность, в которой поток  сначала будет выполнено, чтобы преодолеть эту ситуацию, мы должны синхронизировать общий ресурс, в
 в моем случае используется функция печати, к которой обращаются два потока.

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();  
    }
}

Ответ 14

Это мое решение проблемы. У меня есть два класса, реализующих Runnable, один печатает нечетную последовательность, а другой печатает четную. У меня есть экземпляр Object, который я использую для блокировки. Я инициализирую два класса одним и тем же объектом. Существует synchronized block внутри метода run двух классов, где внутри цикла каждый метод печатает одно из чисел, уведомляет другой поток, ожидая блокировки на том же объекте, а затем сам ожидает той же блокировки снова.

Классы:

public class PrintEven implements Runnable{
private Object lock;
public PrintEven(Object lock) {
    this.lock =  lock;
}
@Override
public void run() {
    synchronized (lock) {
        for (int i = 2; i <= 10; i+=2) {
            System.out.println("EVEN:="+i);
            lock.notify();
            try {
                //if(i!=10) lock.wait();
                lock.wait(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

  }
}


public class PrintOdd implements Runnable {
private Object lock;
public PrintOdd(Object lock) {
    this.lock =  lock;
}
@Override
public void run() {
    synchronized (lock) {
        for (int i = 1; i <= 10; i+=2) {
            System.out.println("ODD:="+i);
            lock.notify();
            try {
                //if(i!=9) lock.wait();
                lock.wait(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
}

public class PrintEvenOdd {
public static void main(String[] args){
    Object lock = new Object(); 
    Thread thread1 =  new Thread(new PrintOdd(lock));
    Thread thread2 =  new Thread(new PrintEven(lock));
    thread1.start();
    thread2.start();
}
}

В моем примере верхний предел равен 10. Как только нечетный поток печатает 9 или четный поток печатает 10, нам больше не нужны никакие потоки для ожидания. Таким образом, мы можем справиться с этим, используя один if-block. Или мы можем использовать перегруженный метод wait(long timeout) для ожидания ожидания. Здесь есть один недостаток. С помощью этого кода мы не можем гарантировать, какой поток начнет выполнение первым.

Другой пример, используя Lock and Condition

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockConditionOddEven {
 public static void main(String[] args) {
    Lock lock =  new ReentrantLock();
    Condition evenCondition = lock.newCondition();
    Condition oddCondition = lock.newCondition();
    Thread evenThread =  new Thread(new EvenPrinter(10, lock, evenCondition, oddCondition));
    Thread oddThread =  new Thread(new OddPrinter(10, lock, evenCondition, oddCondition));
    oddThread.start();
    evenThread.start();
}

static class OddPrinter implements Runnable{
    int i = 1;
    int limit;
    Lock lock;
    Condition evenCondition;
    Condition oddCondition;

    public OddPrinter(int limit) {
        super();
        this.limit = limit;
    }

    public OddPrinter(int limit, Lock lock, Condition evenCondition, Condition oddCondition) {
        super();
        this.limit = limit;
        this.lock = lock;
        this.evenCondition = evenCondition;
        this.oddCondition = oddCondition;
    }

    @Override
    public void run() {
        while( i <=limit) {
            lock.lock();
            System.out.println("Odd:"+i);
            evenCondition.signal();
            i+=2;
            try {
                oddCondition.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
}

static class EvenPrinter implements Runnable{
    int i = 2;
    int limit;
    Lock lock;
    Condition evenCondition;
    Condition oddCondition;

    public EvenPrinter(int limit) {
        super();
        this.limit = limit;
    }


    public EvenPrinter(int limit, Lock lock, Condition evenCondition, Condition oddCondition) {
        super();
        this.limit = limit;
        this.lock = lock;
        this.evenCondition = evenCondition;
        this.oddCondition = oddCondition;
    }


    @Override
    public void run() {
        while( i <=limit) {
            lock.lock();
            System.out.println("Even:"+i);
            i+=2;
            oddCondition.signal();
            try {
                evenCondition.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
}

}

Ответ 15

Вот рабочий код для печати нечетных, даже не используя механизм ожидания и уведомления. Я ограничиваю предел чисел для печати от 1 до 50.

public class NotifyTest {
    Object ob=new Object(); 

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    NotifyTest nt=new NotifyTest();

    even e=new even(nt.ob);     
    odd o=new odd(nt.ob);

    Thread t1=new Thread(e);
    Thread t2=new Thread(o);

    t1.start();     
    t2.start();
    }
}    

class even implements Runnable
{
    Object lock;        
    int i=2;

    public even(Object ob)
    {
        this.lock=ob;       
    }

    @Override
    public void run() {
    // TODO Auto-generated method stub      
        while(i<=50)
        {
            synchronized (lock) {               
            try {
                lock.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("Even Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i);
            i=i+2;              
        }           
    }       
} 

class odd implements Runnable
{

    Object lock;
    int i=1;    

    public odd(Object ob)
    {
        this.lock=ob;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(i<=49)
        {
            synchronized (lock) {               
            System.out.println("Odd Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i);
            i=i+2;              
            lock.notify();
            }
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }       
}

Ответ 16

Ниже приводится моя реализация с использованием 2 Семафоров.

  • Нечетный семафор с разрешением 1.
  • Даже Семафор с разрешением 0.
  • Передайте два Семафора в оба потока как следующую подпись (мой, другой): -
  • В Нечетный поток проходит в порядке (нечетно, четно)
  • To Even thread pass в этом порядке (четный, нечетный)
  • run() логика метода - my.acquireUninterruptibly() → Print → other.release()
  • В потоке Even, поскольку даже Sema равен 0, он будет блокироваться.
  • В нечетном потоке, когда нечетная Sema доступна (от init до 1), это будет печатать 1, а затем освобождать даже Sema, позволяя запустить Even thread.
  • Даже поток запускает отпечатки 2 и освобождает нечетную Sema, позволяющую работать с нечетным потоком.

    import java.util.concurrent.Semaphore;
    
    
    public class EvenOdd {
    private final static String ODD = "ODD";
    private final static String EVEN = "EVEN";
    private final static int MAX_ITERATIONS = 10;
    
    public static class EvenOddThread implements Runnable {     
        private String mType;
        private int  mNum;
        private Semaphore mMySema;
        private Semaphore mOtherSema;
    
        public EvenOddThread(String str, Semaphore mine, Semaphore other) {
            mType = str;
            mMySema = mine;//new Semaphore(1); // start out as unlocked
            mOtherSema = other;//new Semaphore(0);
            if(str.equals(ODD)) {
                mNum = 1;
            }
            else {
                mNum = 2;
            }
        }
    
        @Override
        public void run() {         
    
                for (int i = 0; i < MAX_ITERATIONS; i++) {
                    mMySema.acquireUninterruptibly();
                    if (mType.equals(ODD)) {
                        System.out.println("Odd Thread - " + mNum);
                    } else {
                        System.out.println("Even Thread - " + mNum);
                    }
                    mNum += 2;
                    mOtherSema.release();
                }           
        }
    
    }
    
        public static void main(String[] args) throws InterruptedException {
            Semaphore odd = new Semaphore(1);
            Semaphore even = new Semaphore(0);
    
            System.out.println("Start!!!");
            System.out.println();
    
            Thread tOdd = new Thread(new EvenOddThread(ODD, 
                                     odd, 
                                     even));
            Thread tEven = new Thread(new EvenOddThread(EVEN, 
                                     even, 
                                     odd));
    
            tOdd.start();
            tEven.start();
    
            tOdd.join();
            tEven.join();
    
            System.out.println();
            System.out.println("Done!!!");
        }       
    
    }
    

Ниже приведен вывод: -

Start!!!

Odd Thread - 1
Even Thread - 2
Odd Thread - 3
Even Thread - 4
Odd Thread - 5
Even Thread - 6
Odd Thread - 7
Even Thread - 8
Odd Thread - 9
Even Thread - 10
Odd Thread - 11
Even Thread - 12
Odd Thread - 13
Even Thread - 14
Odd Thread - 15
Even Thread - 16
Odd Thread - 17
Even Thread - 18
Odd Thread - 19
Even Thread - 20

Done!!!

Ответ 17

Я думаю, что предоставляемые решения излишне добавили материал и не используют семафоры в полном объеме. Здесь мое решение.

package com.test.threads;

import java.util.concurrent.Semaphore;

public class EvenOddThreadTest {

    public static int MAX = 100;
    public static Integer number = new Integer(0);

    //Unlocked state
    public Semaphore semaphore = new Semaphore(1);
    class PrinterThread extends Thread {

        int start = 0;
        String name;

        PrinterThread(String name ,int start) {
            this.start = start;
            this.name = name;
        }

        @Override
        public void run() {
            try{
                while(start < MAX){
                    // try to acquire the number of semaphore equal to your value
                    // and if you do not get it then wait for it.
                semaphore.acquire(start);
                System.out.println(name + " : " + start);
                // prepare for the next iteration.
                start+=2;
                // release one less than what you need to print in the next iteration.
                // This will release the other thread which is waiting to print the next number.
                semaphore.release(start-1);
                }
            } catch(InterruptedException e){

            }
        }
    }

    public static void main(String args[]) {
        EvenOddThreadTest test = new EvenOddThreadTest();
        PrinterThread a = test.new PrinterThread("Even",1);
        PrinterThread b = test.new PrinterThread("Odd", 2);
        try {
            a.start();
            b.start();
        } catch (Exception e) {

        }
    }
}

Ответ 18

package com.example;

public class MyClass  {
    static int mycount=0;
    static Thread t;
    static Thread t2;
    public static void main(String[] arg)
    {
        t2=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.print(mycount++ + " even \n");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(mycount>25)
                    System.exit(0);
                run();
            }
        });
        t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.print(mycount++ + " odd \n");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(mycount>26)
                    System.exit(0);
                run();
            }
        });
        t.start();
        t2.start();
    }
}

Ответ 19

Рабочее решение с использованием одного класса

package com.fursa.threads;

   public class PrintNumbers extends Thread {

     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");
        even.start();
        odd.start();

    }

    @Override
    public void run() {
        for(int i=0;i<=100;i++) {

            synchronized (lock) {

                if (Thread.currentThread().getName().equals("Even")) {

                    if(i % 2 == 0 ){
                        System.out.println(Thread.currentThread().getName() + " - "+ i);
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }                   
                    else if (i % 2 != 0 ) {
                        lock.notify();
                    }
                }

                if (Thread.currentThread().getName().equals("Odd")) {

                    if(i % 2 == 1 ){
                        System.out.println(Thread.currentThread().getName() + " - "+ i);
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }                   
                    else if (i % 2 != 1 ) {
                        lock.notify();
                    }
                }

            }
        }
    }
}

Ответ 20

Вы можете использовать следующий код, чтобы получить результат с созданием двух анонимных классов потоков.

package practice;

class Display {
    boolean isEven = false;

    synchronized public void printEven(int number) throws InterruptedException {
        while (isEven)
            wait();
        System.out.println("Even : " + number);
        isEven = true;
        notify();
    }

    synchronized public void printOdd(int number) throws InterruptedException {
        while (!isEven)
            wait();
        System.out.println("Odd : " + number);
        isEven = false;
        notify();
    }
}

public class OddEven {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        final Display disp = new Display();


        new Thread() {
            public void run() {
                int num = 0;
                for (int i = num; i <= 10; i += 2) {
                    try {
                        disp.printEven(i);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        new Thread() {
            public void run() {
                int num = 1;
                for (int i = num; i <= 10; i += 2) {
                    try {
                        disp.printOdd(i);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

}

Ответ 21

Это может быть достигнуто с помощью Lock и Condition:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class EvenOddThreads {

    public static void main(String[] args) throws InterruptedException {
        Printer p = new Printer();
        Thread oddThread = new Thread(new PrintThread(p,false),"Odd  :");
        Thread evenThread = new Thread(new PrintThread(p,true),"Even :");
        oddThread.start();
        evenThread.start();
    }

}

class PrintThread implements Runnable{
    Printer p;
    boolean isEven = false;

    PrintThread(Printer p, boolean isEven){
        this.p = p;
        this.isEven = isEven;
    }

    @Override
    public void run() {
        int i = (isEven==true) ? 2 : 1;
        while(i < 10 ){
            if(isEven){
                p.printEven(i);
            }else{
                p.printOdd(i);
            }
            i=i+2;
        }
    }
}

class Printer{

    boolean isEven = true;
    Lock lock = new ReentrantLock();
    Condition condEven = lock.newCondition();
    Condition condOdd = lock.newCondition();

    public void printEven(int no){
        lock.lock();
        while(isEven==true){
            try {
                condEven.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() +no);
        isEven = true;
        condOdd.signalAll();
        lock.unlock();
    }

    public void printOdd(int no){
        lock.lock();
        while(isEven==false){
            try {
                condOdd.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() +no);
        isEven = false;
        condEven.signalAll();
        lock.unlock();
    }
}

Ответ 22

Класс для печати нечетных Четное число

public class PrintOddEven implements Runnable {

    private int max;
    private int number;

    public  PrintOddEven(int max_number,int number) {
        max = max_number;
        this.number = number;
    }

    @Override
    public void run() {


        while(number<=max)
        {
            if(Thread.currentThread().getName().equalsIgnoreCase("odd"))
            {
                try {
                    printOdd();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else
            {
                try {
                    printEven();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }


    }

    public synchronized void printOdd() throws InterruptedException
    {

        if(number%2==0)
        {
            wait();
        }

        System.out.println(number+Thread.currentThread().getName());
        number++;
        notifyAll();
    }

    public synchronized void printEven() throws InterruptedException
    {

        if(number%2!=0)
        {
            wait();
        }

        System.out.println(number+Thread.currentThread().getName());
        number++;
        notifyAll();
    }

}

Программа драйверов

public class OddEvenThread {

    public static void main(String[] args) {

        PrintOddEven printer = new PrintOddEven(10,1);  
        Thread thread1 = new Thread(printer,"odd");
        Thread thread2 = new Thread (printer,"even");

        thread1.start();
        thread2.start();

    }

}

Ответ 23

public class Solution {

 static class NumberGenerator{

     private static volatile boolean printEvenNumber = false;


     public  void printEvenNumber(int i) {
         synchronized (this) {
             if(!printEvenNumber) {
                 try {
                     wait();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
             System.out.println(i);
             printEvenNumber = !printEvenNumber;
             notify();
         }
     }

     public  void printOddNumber(int i ) {
            synchronized (this) {
                if(printEvenNumber) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println(i);
                printEvenNumber = !printEvenNumber;
                notify();
            }
     }

}

static  class OddNumberGenerator implements Runnable{
    private NumberGenerator numberGenerator;

    public OddNumberGenerator(NumberGenerator numberGenerator) {
        this.numberGenerator = numberGenerator;
    }

    @Override
    public void run() {
        for(int i  = 1; i <100; i = i + 2) {
            numberGenerator.printOddNumber(i);
        }
    }
}

static class EvenNumberGenerator implements Runnable {
    private NumberGenerator numberGenerator;

    public EvenNumberGenerator(NumberGenerator numberGenerator) {
        this.numberGenerator = numberGenerator;
    }

    @Override
    public void run() {
        for (int i = 2; i <= 100; i =  i + 2) {
           numberGenerator.printEvenNumber(i);
        }
    }
}


public static void main(String[] args) {
    NumberGenerator ng = new NumberGenerator();
    OddNumberGenerator oddNumberGenerator = new OddNumberGenerator(ng);
    EvenNumberGenerator evenNumberGenerator = new EvenNumberGenerator(ng);
    new Thread(oddNumberGenerator).start();
    new Thread(evenNumberGenerator).start();

}

}

Ответ 24

public class ThreadEvenOdd {
  static int cnt=0;
  public static void main(String[] args) {

    Thread t1 = new Thread(new Runnable() {

      @Override
      public void run() {
        synchronized(this) {
          while(cnt<101) {
            if(cnt%2==0) {
              System.out.print(cnt+" ");
              cnt++;
            }
            notifyAll();
          }
        }
      }

    });
    Thread t2 = new Thread(new Runnable() {

      @Override
      public void run() {
        synchronized(this) {
          while(cnt<101) {
            if(cnt%2==1) {
              System.out.print(cnt+" ");
              cnt++;
            }
            notifyAll();
          }
        }
      }
    });

    t1.start();
    t2.start();
  }
}

Ответ 25

        public class OddAndEvenThreadProblems {
            private static Integer i = 0;

            public static void main(String[] args) {
                new EvenClass().start();
                new OddClass().start();

            }

            public static class EvenClass extends Thread {

                public void run() {
                    while (i < 10) {
                        synchronized (i) {
                            if (i % 2 == 0 ) {
                                try {
                                    Thread.sleep(1000);
                                    System.out.println(" EvenClass " + i);
                                    i = i + 1;
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }

                            }
                        }
                    }
                }
            }

            public static class OddClass extends Thread {

                @Override
                public void run() {
                    while (i < 10) {
                        synchronized (i) {
                            if (i % 2 == 1) {
                                try {
                                    Thread.sleep(1000);
                                    System.out.println(" OddClass  " + i);
                                    i = i + 1;
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }

                            }
                    }
                }
            }
        }
    }





OUTPUT will be :- 

 EvenClass 0
 OddClass  1
 EvenClass 2
 OddClass  3
 EvenClass 4
 OddClass  5
 EvenClass 6
 OddClass  7
 EvenClass 8
 OddClass  9

Ответ 26

package programs.multithreading;

public class PrintOddEvenNoInSequence {

final int upto;
final PrintOddEvenNoInSequence obj;
volatile boolean oddFlag,evenFlag;
public PrintOddEvenNoInSequence(int upto){
    this.upto = upto;
    obj = this;
    oddFlag = true;
    evenFlag = false;
}
void printInSequence(){

    Thread odd = new Thread(new Runnable() {
        @Override
        public void run() {
            for(int i = 1; i <= upto; i = i + 2){
                synchronized (obj) {
                    while(!oddFlag){
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Odd:"+i);
                    oddFlag = false;
                    evenFlag = true;
                    obj.notify();
                }
            }
        }
    });

    Thread even = new Thread(new Runnable() {
        @Override
        public void run() {
            for(int i = 2; i <= upto; i = i + 2){
                synchronized (obj) {
                    while(!evenFlag){
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Even:"+i);
                    oddFlag = true;
                    evenFlag = false;
                    obj.notify();
                }
            }
        }
    });

    odd.start();
    even.start();

}
public static void main(String[] args) {
    new PrintOddEvenNoInSequence(100).printInSequence();
}
}

Ответ 27

package example;

public class PrintSeqTwoThreads {

    public static void main(String[] args) {
        final Object mutex = new Object();
        Thread t1 = new Thread() {
            @Override
            public void run() {
                for (int j = 0; j < 10;) {
                    synchronized (mutex) {
                        System.out.println(Thread.currentThread().getName() + " " + j);
                        j = j + 2;
                        mutex.notify();
                        try {
                            mutex.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        Thread t2 = new Thread() {
            @Override
            public void run() {
                for (int j = 1; j < 10;) {
                    synchronized (mutex) {
                        System.out.println(Thread.currentThread().getName() + " " + j);
                        j = j + 2;
                        mutex.notify();
                        try {
                            mutex.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        t1.start();
        t2.start();
    }
}

Ответ 28

Пожалуйста, используйте следующий код для печати нечетного и четного числа в правильном порядке вместе с желаемыми сообщениями.

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");
  }
}

Ответ 29

Я не мог понять большинство кодов, которые были здесь, поэтому я написал сам, возможно, это помогает кому-то вроде меня:

ПРИМЕЧАНИЕ. Это не использует отдельный режим печати и нечетный. Один метод print() делает все это.

public class test {

    private static int START_INT = 1;
    private static int STOP_INT = 10;
    private static String THREAD_1 = "Thread A";
    private static String THREAD_2 = "Thread B";

    public static void main(String[] args) {
        SynchronizedRepository syncRep = new SynchronizedRepository(START_INT,STOP_INT);
        Runnable r1 = new EvenOddWorker(THREAD_1,syncRep);
        Runnable r2 = new EvenOddWorker(THREAD_2,syncRep);
        Thread t1 = new Thread(r1, THREAD_1);
        Thread t2 = new Thread(r2, THREAD_2);
        t1.start();
        t2.start();
    }

}




public class SynchronizedRepository {
    private volatile int number;
    private volatile boolean isSlotEven;
    private int startNumber;
    private int stopNumber;

    public SynchronizedRepository(int startNumber, int stopNumber) {
        super();
        this.number = startNumber;
        this.isSlotEven = startNumber%2==0;
        this.startNumber = startNumber;
        this.stopNumber = stopNumber;
    }


    public synchronized void print(String threadName) {
        try {
            for(int i=startNumber; i<=stopNumber/2; i++){
                if ((isSlotEven && number % 2 == 0)||
                        (!isSlotEven && number % 2 != 0)){
                    System.out.println(threadName + " "+ number);
                    isSlotEven = !isSlotEven;
                    number++;
                }
                notifyAll();
                wait();
            }
            notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}



public class EvenOddWorker implements Runnable {

    private String threadName;
    private SynchronizedRepository syncRep;

    public EvenOddWorker(String threadName, SynchronizedRepository syncRep) {
        super();
        this.threadName = threadName;
        this.syncRep = syncRep;
    }

    @Override
    public void run() {
        syncRep.print(threadName);
    }

}

Ответ 30

Простое решение:)

package com.code.threads;

public class PrintOddEven extends Thread {

    private Object lock;
    static volatile int count = 1;

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

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

    public static void main(String[] args) {
        Object obj = new Object();
        PrintOddEven even = new PrintOddEven(obj);
        PrintOddEven odd = new PrintOddEven(obj);

        even.start();
        odd.start();
    }
}