如何使用Java中的两个线程输出偶数和奇数?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (162)

我用了以下的代码,主要为了按顺序输出偶数和奇数,但是没有输出正确的结果

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

}

有人能帮我解决这个问题吗?

预期输出结果:奇数:1偶数:2奇偶:3偶数:4奇数:5偶数:6奇数:7偶数:8奇数:9偶数

提问于
用户回答回答于

可以消除“偶数或奇数”问题,并使用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();
    }
}

热门问答

云服务器中ping不可达,请教一下如何恢复?

推荐已采纳
本地主机 ping 不通实例可能由以下问题导致: 目标服务器的设置不正确 域名没有正确解析 链路故障 在确保本地网络正常的前提下(即您可以正常 ping 通其他网站),可根据以下操作进行排查: 检查实例是否配置公网 IP 检查安全组设置 检查系统设置 检查域名是否备案 检查域名解...... 展开详请

为什么加固之后生成四个文件?

腾讯云@移动安全

腾讯 · 移动开发工程师 (已认证)

腾讯云移动安全前端开发
推荐

选择最后一个_legu_aligned_signed.apk 文件,这个是加固并已重签名的文件。

COS Javascript SDK 为何没有 getService 方法?

因为 getService 请求的是 service.cos.myqcloud.com 或 cos.<Region>.myqcloud.com 域名,前端直接请求会导致跨域问题。 前端 js sdk 直接请求 bucket/object 相关的接口,虽然也会跨域,但你可以在 你...... 展开详请

iot设备通过mqtt协议连接,没有办法设置clientid?

DylanRichard

腾讯 · 产品经理 (已认证)

万物互联的时代,欢迎来到IoT的世界
推荐

物联网接入层有设备互踢的逻辑,如果是用同一个设备 ID 在不同地方登录,会导致其中一方被另一方踢下线。因此发现设备一直上下线时,需要确认是否有不同的人或者多线程在使用同一个设备 ID 执行登录操作。

实时语音识别支持c#平台吗?

支持的。虽然SDK没有C#的,但是可以通过API进行请求

如何延长签名有效期?

yinshawnrao

腾讯 · Web开发工程师 (已认证)

腾讯云搬砖工
推荐

如果需要自己生成签名,可以使用对象存储COS的SDK工具,里面有提供方法,获取下载链接,签名时间可以参数控制。

https://cloud.tencent.com/document/product/436/7753

所属标签

扫码关注云+社区

领取腾讯云代金券