简体   繁体   English

在 Java 中使用两个线程打印偶数和奇数

[英]Printing Even and Odd using two Threads in Java

I tried the code below.我尝试了下面的代码。 I took this piece of code from some other post which is correct as per the author.我从其他帖子中获取了这段代码,根据作者的说法,这是正确的。 But when I try running, it doesn't give me the exact result.但是当我尝试运行时,它并没有给我确切的结果。

This is mainly to print even and odd values in sequence.这主要是顺序打印偶数和奇数。

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

}

Can someone help me in fixing this?有人可以帮我解决这个问题吗?

EDIT Expected result: Odd:1 Even:2 Odd:3 Even:4 Odd:5 Even:6 Odd:7 Even:8 Odd:9编辑预期结果:奇数:1 偶数:2 奇数:3 偶数:4 奇数:5 偶数:6 奇数:7 偶数:8 奇数:9

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

Use this following very simple JAVA 8 Runnable Class feature使用以下非常简单的 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();

}
}

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

This is easiest solution for this problem.这是解决此问题的最简单方法。

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

    }
}

Simplest Solution!!最简单的解决方案!!

public class OddEvenWithThread {
    public static void main(String a[]) {
        Thread t1 = new Thread(new OddEvenRunnable(0), "Even Thread");
        Thread t2 = new Thread(new OddEvenRunnable(1), "Odd Thread");

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

class OddEvenRunnable implements Runnable {
    Integer evenflag;
    static Integer number = 1;
    static Object lock = new Object();

    OddEvenRunnable(Integer evenFlag) {
        this.evenflag = evenFlag;
    }

    @Override
    public void run() {
        while (number < 10) {
            synchronized (lock) {
                try {
                    while (number % 2 != evenflag) {
                        lock.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

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

The same can be done with Lock interface: 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();
    }
}

This code will also work fine.这段代码也能正常工作。

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

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

The other question was closed as a duplicate of this one.另一个问题作为此问题的副本而关闭。 I think we can safely get rid of "even or odd" problem and use the wait/notify construct as follows:我认为我们可以安全地摆脱“偶数或奇数”问题并使用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();
    }
}
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();
    }
}
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();

    }

}

I have done it this way, while printing using two threads we cannot predict the sequence which thread我是这样做的,在使用两个线程打印时,我们无法预测哪个线程的顺序
would get executed first so to overcome this situation we have to synchronize the shared resource,in将首先执行,因此为了克服这种情况,我们必须同步共享资源,在
my case the print function which two threads are trying to access.我的情况是两个线程试图访问的打印函数。

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

This is my solution to the problem.这是我对问题的解决方案。 I have two classes implementing Runnable , one prints odd sequence and the other prints even.我有两个实现Runnable类,一个打印奇数序列,另一个打印偶数。 I have an instance of Object , that I use for lock.我有一个Object实例,用于锁定。 I initialize the two classes with the same object.我用同一个对象初始化这两个类。 There is a synchronized block inside the run method of the two classes, where, inside a loop, each method prints one of the numbers, notifies the other thread, waiting for lock on the same object and then itself waits for the same lock again.这两个类的 run 方法内部有一个synchronized block ,其中,在一个循环中,每个方法打印一个数字,通知另一个线程,等待对同一对象的锁定,然后自己再次等待相同的锁定。

The classes :课程:

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

The upper limit in my example is 10. Once the odd thread prints 9 or the even thread prints 10, then we don't need any of the threads to wait any more.我的例子中的上限是 10。一旦奇数线程打印 9 或偶数线程打印 10,那么我们就不需要任何线程再等待了。 So, we can handle that using one if-block .所以,我们可以使用一个if-block来处理。 Or, we can use the overloaded wait(long timeout) method for the wait to be timed out.或者,我们可以使用重载的wait(long timeout)方法让等待超时。 One flaw here though.不过这里有一个缺陷。 With this code, we cannot guarantee which thread will start execution first.使用此代码,我们无法保证哪个线程将首先开始执行。

Another example, using 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();
            }
        }
    }
}

} }

Here is the working code to print odd even no alternatively using wait and notify mechanism.这是使用等待和通知机制打印奇偶数的工作代码。 I have restrict the limit of numbers to print 1 to 50.我限制了打印 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();
            }
        }
    }       
}

Following is my implementation using 2 Semaphores.以下是我使用 2 个信号量的实现。

  1. Odd Semaphore with permit 1.具有许可 1 的奇数信号量。
  2. Even Semaphore with permit 0.即使是许可为 0 的信号量。
  3. Pass the two Semaphores to both threads as following signature (my, other):-将两个信号量作为以下签名(我的,其他)传递给两个线程:-
  4. To Odd thread pass in the order (odd, even)按顺序传递奇数线程(奇数,偶数)
  5. To Even thread pass in this order (even, odd)偶数线程按此顺序传递(偶数,奇数)
  6. run() method logic is my.acquireUninterruptibly() -> Print -> other.release() run() 方法逻辑是 my.acquireUninterruptably() -> Print -> other.release()
  7. In Even thread as even Sema is 0 it will block.在偶数线程中,偶数 Sema 为 0 它将阻塞。
  8. In Odd thread as odd Sema is available (init to 1) this will print 1 and then release even Sema allowing Even thread to run.在奇数线程中,由于奇数 Sema 可用(初始化为 1),这将打印 1,然后释放偶数 Sema,允许偶数线程运行。
  9. Even thread runs prints 2 and release odd Sema allowing Odd thread to run.偶数线程运行打印 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!!!"); } }

Following is the output:-以下是输出:-

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!!!

I think the solutions being provided have unnecessarily added stuff and does not use semaphores to its full potential.我认为所提供的解决方案增加了不必要的内容,并且没有充分发挥信号量的潜力。 Here's what my solution is.这是我的解决方案。

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

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

Working solution using single class使用单个类的工作解决方案

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

            }
        }
    }
}

You can use the following code to get the output with creating two anonymous thread classes.您可以使用以下代码通过创建两个匿名线程类来获取输出。

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

}

This can be acheived using Lock and Condition :这可以使用 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();
    }
}

Class to print odd Even number打印奇偶数的类

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

}

Driver Program驱动程序

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

    }

}

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

}

} }

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

Please use the following code to print odd and even number in a proper order along with desired messages.请使用以下代码以正确的顺序打印奇数和偶数以及所需的消息。

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

I could not understand most of the codes that were here so I wrote myself one, maybe it helps someone like me:我无法理解这里的大部分代码,所以我自己写了一个,也许它可以帮助像我这样的人:

NOTE: This does not use separate print even and odd method.注意:这不使用单独打印偶数和奇数方法。 One method print() does it all.一种方法 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);
    }

}

Simple solution :)简单的解决方案:)

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();
    }
}
public class Main {
    public static void main(String[] args) throws Exception{
        int N = 100;
        PrintingThread oddNumberThread = new PrintingThread(N - 1);
        PrintingThread evenNumberThread = new PrintingThread(N);
        oddNumberThread.start();
        // make sure that even thread only start after odd thread
        while (!evenNumberThread.isAlive()) {
            if(oddNumberThread.isAlive()) {
                evenNumberThread.start();
            } else {
                Thread.sleep(100);
            }
        }

    }
}

class PrintingThread extends Thread {
    private static final Object object = new Object(); // lock for both threads
    final int N;
    // N determines whether given thread is even or odd
    PrintingThread(int N) {
        this.N = N;
    }

    @Override
    public void run() {
        synchronized (object) {
            int start = N % 2 == 0 ? 2 : 1; // if N is odd start from 1 else start from 0
            for (int i = start; i <= N; i = i + 2) {
                System.out.println(i);
                try {
                    object.notify(); // will notify waiting thread
                    object.wait(); // will make current thread wait
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

See the Clean implementation 请参阅Clean实施

public class PrintOddEvenByTwoThreads {
    static int number = 1;
    static Thread odd;
    static Thread even;
    static int max = 10;

    static class OddThread extends Thread {
        @Override
        public void run() {
            while (number <= max) {
                if (number % 2 == 1) {
                    System.out.println(Thread.currentThread() + "" + number++);
                } else {

                    synchronized (odd) {
                        synchronized (even) {
                            even.notify();
                        }
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    static class EvenThread extends Thread {
        @Override
        public void run() {
            while (number <= max) {
                if (number % 2 == 0) {
                    System.out.println(Thread.currentThread() + "" + number++);
                } else {

                    synchronized (even) {
                        synchronized (odd) {
                            odd.notify();
                        }
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        odd = new OddThread();
        even = new EvenThread();
        odd.start();
        even.start();
    }
}
class PrintNumberTask implements Runnable {
Integer count;
Object lock;

PrintNumberTask(int i, Object object) {
    this.count = i;
    this.lock = object;
}

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

} }

This solution works for me (Java 8 and above used Lamda expression)这个解决方案对我有用(Java 8 及更高版本使用 Lamda 表达式)

public class EvenOddUsingThread {

    static int number = 100;
    static int counter = 1;

    public static void main(String[] args) {
        EvenOddUsingThread eod = new EvenOddUsingThread();
        Thread t1 = new Thread(() -> eod.printOdd());
        Thread t2 = new Thread(() -> eod.printEven());
        t1.start();
        t2.start();
    }

    public void printOdd() {
        synchronized (this) {
            while (counter < number) {
                if (counter % 2 == 0) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
                // Print the number
                System.out.println(counter + " Thread Name: " + Thread.currentThread().getName());
                // Increment counter
                counter++;
                // Notify to second thread
                notify();
            }
        }
    }

    public void printEven() {
        synchronized (this) {
            while (counter < number) {
                if (counter % 2 == 1) {
                    try {
                        wait();
                    } catch (InterruptedException ignored) {
                    }
                }
                // Print the number
                System.out.println(counter + " Thread Name: " + Thread.currentThread().getName());
                // Increment counter
                counter++;
                // Notify to second thread
                notify();
            }
        }
    }

}

The solution below is using java 8 completable future and executor service to print even and odd numbers using two threads.下面的解决方案是使用 java 8 completable future and executor service 来使用两个线程打印偶数和奇数。

ExecutorService firstExecutorService = Executors.newSingleThreadExecutor(r -> {
        Thread t = new Thread(r);
        t.setName("first");
        return t;
    });

    ExecutorService secondExecutorService = Executors.newSingleThreadExecutor(r -> {
        Thread t = new Thread(r);
        t.setName("second");
        return t;
    });

    IntStream.range(1, 101).forEach(num -> {

        CompletableFuture<Integer> thenApplyAsync = CompletableFuture.completedFuture(num).thenApplyAsync(x -> {

            if (x % 2 == 1) {
                System.out.println(x + " " + Thread.currentThread().getName());
            }
            return num;
        }, firstExecutorService);

        thenApplyAsync.join();

        CompletableFuture<Integer> thenApplyAsync2 = CompletableFuture.completedFuture(num).thenApplyAsync(x -> {
            if (x % 2 == 0) {
                System.out.println(x + " " + Thread.currentThread().getName());
            }
            return num;
        }, secondExecutorService);

        thenApplyAsync2.join();
    });

    firstExecutorService.shutdown();
    secondExecutorService.shutdown();

The below is the console log of it.下面是它的控制台日志。
在此处输入图像描述

We can print odd and even using two separate threads using CompletableFuture as well:我们也可以使用CompletableFuture使用两个单独的线程打印奇数和偶数:

import java.util.concurrent.CompletableFuture;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;

public class OddEvenBy2Thread {

    private static Object object = new Object();

    private static IntPredicate evenCondition = e -> e % 2 == 0;
    private static IntPredicate oddCondition = e -> e % 2 != 0;

    public static void main(String[] args) throws InterruptedException {

        // Odd number printer
        CompletableFuture.runAsync(() -> OddEvenBy2Thread.printNumber(oddCondition));

        // Even number printer
        CompletableFuture.runAsync(() -> OddEvenBy2Thread.printNumber(evenCondition));

        Thread.sleep(1000);
    }

    public static void printNumber(IntPredicate condition){
        IntStream.rangeClosed(1, 10).filter(condition).forEach(OddEvenBy2Thread::execute);
    }

    public static void execute(int num){
        synchronized (object){
            try{
                System.out.println(Thread.currentThread().getName()+" : "+num);
                object.notify();
                object.wait();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }

    }
}

public class EvenOddex {公共 class EvenOddex {

public static class print {

    int n;
    boolean isOdd = false;

    synchronized public void printEven(int n) {

        while (isOdd) {
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(EvenOddex.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

        System.out.print(Thread.currentThread().getName() + n + "\n");

        isOdd = true;
        notify();
    }

    synchronized public void printOdd(int n) {
        while (!isOdd) {
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(EvenOddex.class.getName()).log(Level.SEVERE, null, ex);
            }
        }


        System.out.print(Thread.currentThread().getName() + n + "\n");
        isOdd = false;
        notify();



    }
}

public static class even extends Thread {

    print po;

    even(print po) {

        this.po = po;

        new Thread(this, "Even").start();

    }

    @Override
    public void run() {


        for (int j = 0; j < 10; j++) {
            if ((j % 2) == 0) {
                po.printEven(j);
            }
        }

    }
}

public static class odd extends Thread {

    print po;

    odd(print po) {

        this.po = po;
        new Thread(this, "Odd").start();
    }

    @Override
    public void run() {

        for (int i = 0; i < 10; i++) {

            if ((i % 2) != 0) {
                po.printOdd(i);
            }
        }

    }
}

public static void main(String args[]) {
    print po = new print();
    new even(po);
    new odd(po);

}

} }

public class Multi extends Thread{  
    public static int a;
    static{a=1;}
    public void run(){  
        for(int i=1;i<5;i++){  
        System.out.println("Thread Id  "+this.getId()+"  Value "+a++);
        try{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}  

        }  
    }  
public static void main(String args[]){  
       Multi t1=new Multi();  
       Multi t2=new Multi();  

      t1.start();  
      t2.start();  
    }  
}  
public class PrintOddEven {
private static class PrinterThread extends Thread {

    private static int current = 0;
    private static final Object LOCK = new Object();

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

    @Override
    public void run() {
        while (true) {
            synchronized (LOCK) {
                try {
                    LOCK.wait(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (current < number) {
                    System.out.println(name + ++current);
                } else {
                    break;
                }

                LOCK.notifyAll();
            }
        }
    }

    int number;
    String name;
}

public static void main(String[] args) {
    new PrinterThread("thread1 : ", 20).start();
    new PrinterThread("thread2 : ", 20).start();
}
}

1- The number is initialized with 1 and isOdd flag is set to false . 1- 数字初始化为 1 并且isOdd标志设置为false set isOdd to trueisOdd设置为true

2- Increment should be by 1 (not by 2) ie number+=1 ; 2- 增量应为 1(而不是 2)即number+=1

import java.util.concurrent.Semaphore;


public class PrintOddAndEven {

private static class OddThread extends Thread {
    private Semaphore semaphore;
    private Semaphore otherSemaphore;
    private int value = 1;

    public  OddThread(Semaphore semaphore, Semaphore otherSemaphore) {
        this.semaphore = semaphore;
        this.otherSemaphore = otherSemaphore;
    }

    public void run() {
        while (value <= 100) {
            try {
                // Acquire odd semaphore
                semaphore.acquire();
                System.out.println(" Odd Thread " + value + " " + Thread.currentThread().getName());

            } catch (InterruptedException excetion) {
                excetion.printStackTrace();
            }
            value = value + 2;
            // Release odd semaphore
            otherSemaphore.release();
        }
    }
}


private static class EvenThread extends Thread {
    private Semaphore semaphore;
    private Semaphore otherSemaphore;

    private int value = 2;

    public  EvenThread(Semaphore semaphore, Semaphore otherSemaphore) {
        this.semaphore = semaphore;
        this.otherSemaphore = otherSemaphore;
    }

    public void run() {
        while (value <= 100) {
            try {
                // Acquire even semaphore
                semaphore.acquire();
                System.out.println(" Even Thread " + value + " " + Thread.currentThread().getName());

            } catch (InterruptedException excetion) {
                excetion.printStackTrace();
            }
            value = value + 2;
            // Release odd semaphore
            otherSemaphore.release();
        }
    }
}


public static void main(String[] args) {
    //Initialize oddSemaphore with permit 1
    Semaphore oddSemaphore = new Semaphore(1);
    //Initialize evenSempahore with permit 0
    Semaphore evenSempahore = new Semaphore(0);
    OddThread oddThread = new OddThread(oddSemaphore, evenSempahore);
    EvenThread evenThread = new EvenThread(evenSempahore, oddSemaphore);
    oddThread.start();
    evenThread.start();
    }
}

Simple Solution below:-下面的简单解决方案:-

package com.test;

class MyThread implements Runnable{

    @Override
    public void run() {
        int i=1;
        while(true) {
            String name=Thread.currentThread().getName();
            if(name.equals("task1") && i%2!=0) {
                System.out.println(name+"::::"+i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else if(name.equals("task2") && i%2==0){
                System.out.println(name+"::::"+i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            i++;
        }

    }

    public static void main(String[] args) {

        MyThread task1=new MyThread();
        MyThread task2=new MyThread();

        Thread t1=new Thread(task1,"task1");
        Thread t2=new Thread(task2,"task2");

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

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM