java - 在 Java 中制作偶数和奇数线程以自然顺序打印数字

标签 java multithreading

我知道之前有人问过这个问题,但我无法弄清楚为什么我的解决方案对我不起作用。我有两个线程偶数和奇数,一个打印偶数,另一个打印奇数。当我启动线程时,我希望输出按数字的自然顺序排列,例如 0 1 2 3.. 等。这是我的代码:- [更新]

public class ThreadCommunication {


public static void main(String... args) throws InterruptedException
{
    final ThreadCommunication obj = new ThreadCommunication();
    Thread even = new Thread(){
        @Override
        public void run()
        {
            for(int i=0;i<10;i=i+2){
                synchronized(obj){
                    System.out.println(i);
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    };
    Thread odd = new Thread(){
        @Override
        public void run()
        {
            for(int i=1;i<10;i=i+2){
                synchronized(obj){
                    System.out.println(i);
                    obj.notify();
                }
            }

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

当我运行上面的代码时,有时它会按预期的自然顺序打印数字,但有时会以其他顺序打印,例如:

0
1
3
5
7
9
2

我在这里做错了什么?

最佳答案

编辑:

volatile static boolean isAlreadyWaiting = false;



Thread even = new Thread() {
            @Override
            public void run() {
                synchronized (obj) {
                    for (int i = 0; i < 10; i = i + 2) {
                        System.out.println(i);
                        try {
                            if (!isAlreadyWaiting) {
                                isAlreadyWaiting = true;
                                obj.wait();
                            }
                            obj.notify();
                            isAlreadyWaiting=false;

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
            }
        };
        Thread odd = new Thread() {
            @Override
            public void run() {
                synchronized (obj) {
                    for (int i = 1; i < 10; i = i + 2) {
                        System.out.println(i);
                        try {
                            if(isAlreadyWaiting){
                            obj.notify();
                            isAlreadyWaiting = false;
                            }
                            if (!isAlreadyWaiting) {
                                isAlreadyWaiting = true;
                                obj.wait();
                            }

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
            }
        };

检查文档

public class IllegalMonitorStateException extends RuntimeException

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

Monitor 属于obj

所以你应该打电话

obj.wait();

obj.notify();

有关所有权的更多信息

This methods (wait or notify) should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:

  1. By executing a synchronized instance method of that object.
  2. By executing the body of a synchronized statement that synchronizes on the object.

    1. For objects of type Class, by executing a synchronized static method of that class.

一次只有一个线程可以拥有一个对象的监视器。

关于java - 在 Java 中制作偶数和奇数线程以自然顺序打印数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35693546/

相关文章:

java - 什么是映射缓冲池/直接缓冲池以及如何增加它们的大小?

java - Spring MVC 文件上传将 null 传递给 Controller

java - 无法读取输入文件 - 读取 jar 文件中包含的图像 - java

c++ - 我可以使用 std::vector::swap 修改共享 vector 吗?

perl - 在 Perl 中编写多线程 TCP 服务器守护进程是个坏主意吗?

java - Facebook 登录按钮适用于我的帐户,但不适用于我 friend 的帐户

java - 我如何查看机器是否尝试连接到我的 (linux) 服务器?

multithreading - Quarkus 应用程序的 @Async 等价物是什么?

java - 为什么在非 JavaFX 线程上可以将文本附加到 TextArea 并滚动?

python - 为什么要锁定线程?