为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

蛊毒传说 2023-05-10 13:46:13
您好,我正在尝试使用名为 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();                    }                }            }        }    }}
查看完整描述

3 回答

?
四季花海

TA贡献1811条经验 获得超5个赞

您需要两个线程之间的一些信号。放置synchronized方法print只是保证一次只有一个线程可以进入该方法。可以使用您的线程Object.wait()和方法。Object.notify{All}()

实际上这是某种Sender-Receiver Synchronization Problem。我调整了您的代码。另外我使用了ExecutorServiceandCallable而不是 extending 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;

    }

  }

}


查看完整回答
反对 回复 2023-05-10
?
慕斯王

TA贡献1864条经验 获得超2个赞

synchronized 用于锁定另一个线程的访问,当被锁定的对象空闲时,它不保证下一个调用哪个线程。您可以使用信号量进行线程间通信:


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

  }


查看完整回答
反对 回复 2023-05-10
?
holdtom

TA贡献1805条经验 获得超10个赞

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

    }

}


查看完整回答
反对 回复 2023-05-10
  • 3 回答
  • 0 关注
  • 136 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信