简体   繁体   English

使用2个线程打印偶数和奇数

[英]print even and odd using 2 threads

Hi I am trying to print even and odd using two threads namedly EvenThread and OddThread, some times I am getting correct result and some times not, could any one please help me. 嗨,我正在尝试使用两个名为EvenThread和OddThread的线程打印偶数和奇数,有时我得到正确的结果,有时却没有,请问有谁能帮我的忙。

package com.java8;

public class EvenOddExample {

    public static synchronized void print(int i,String name){
            System.out.println(i+"--->"+name);
    }
    public static void main(String[] args) throws InterruptedException {
        EvenThread e=   new EvenThread();
        e.start();
        OddThread o=new OddThread();
        o.start();

    }
    public static class EvenThread extends Thread{

        public void run() {
            for(int i=0;i<10;i++){
                if(i%2==0){
                    print(i,"Even");
                }else{
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

        }

    }

    public static class OddThread extends Thread{

        @Override
        public void run() {
            for(int i=1;i<10;i++){
                if(i%2!=0){
                    print(i,"Odd");
                }else{
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

        }

    }
}

You need some signaling between the two threads. 在两个线程之间需要一些信令。 Putting synchronized on the print method simply guarantees, that only one thread can enter the method at a time. synchronized放在print方法上只是保证,一次只能有一个线程可以进入该方法。 To put your threads into order Object.wait() and Object.notify{All}() methods can be used. 要将线程置于顺序中,可以使用Object.wait()Object.notify{All}()方法。

Actually this is some kind of the Sender-Receiver Synchronization Problem . 实际上,这是某种发送方-接收方同步问题 Based on the example of the problem described here (Please read this page in order to understand how this synchronization works) I adapted your code. 基于此处描述的问题示例(请阅读此页面,以了解此同步的工作原理),我修改了您的代码。 Additionally I used ExecutorService and Callable instead of extending Thread , which is bad-practice : 另外,我使用ExecutorServiceCallable而不是扩展Thread这是一种不好的做法

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class EvenOddExample {

  private static boolean evensTurn = true;
  private static Object monitor = new Object();

  public static void print(int i, String name) {
    System.out.println(i + "--->" + name);
  }

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

    final ExecutorService executorService = Executors.newFixedThreadPool(2);
    executorService.submit(new EvenCallable());
    executorService.submit(new OddCallable());
    executorService.shutdown();
  }

  public static class EvenCallable implements Callable<Void> {

    @Override
    public Void call() throws InterruptedException {
      for (int i = 0; i < 10; i++) {
        if (i % 2 == 0) {
          synchronized (monitor) {
            while (!evensTurn) { // not your turn?
              monitor.wait(); // wait for monitor in a loop to handle spurious wakeups
            }
            print(i, "Even");
            evensTurn = false; // next odd needs to run
            monitor.notifyAll(); // wakeup the odd thread
          }
        } else {
          Thread.sleep(1000);
        }
      }
      return null;
    }
  }

  public static class OddCallable implements Callable<Void> {

    @Override
    public Void call() throws InterruptedException {
      for (int i = 1; i < 10; i++) {
        if (i % 2 != 0) {
          synchronized (monitor) {
            while (evensTurn) {
              monitor.wait();
            }
            print(i, "Odd");
            evensTurn = true;
            monitor.notifyAll();
          }
        } else {
          Thread.sleep(1000);
        }
      }
      return null;
    }
  }
}

synchronized is used to lock the access of another thread, when the locked object is free, it does not guarantee which is next called thread. 同步用于锁定另一个线程的访问,当锁定的对象空闲时,它不能保证下一个称为线程。 You can use semaphore to make inter-thread communication: 您可以使用信号量进行线程间通信:

  private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};

  static void print(int i, String name) {
    try {
      semaphores[(i + 1) % 2].acquire();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    System.out.println(i + "--->" + name);
    semaphores[i % 2].release();
  }
public class EvenOddPrinter {
    static boolean flag = true;

    public static void main(String[] args) {
        class Odd implements Runnable {

            @Override
            public void run() {
                for (int i = 1; i <= 10;) {
                    if (EvenOddPrinter.flag) {
                        System.out.println(i + "--->odd");
                        i += 2;
                        EvenOddPrinter.flag = !EvenOddPrinter.flag;
                    }
                }
            }

        }

        class Even implements Runnable {

            @Override
            public void run() {
                for (int i = 2; i <= 10;) {
                    if (!EvenOddPrinter.flag) {
                        System.out.println(i + "---->even");
                        i += 2;
                        EvenOddPrinter.flag = !EvenOddPrinter.flag;
                    }
                }

            }

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

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

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