如何使用循环运行的线程来使用Thread.yield()?

Hen*_*rik 4 java multithreading timer

我有以下情况.我有一个主要在一个线程上运行的应用程序.它已经变大了,所以我想运行一个看门狗线程,只要主线程变成一个不同的代码/方法/类块,就会调用它,这样我就可以看到代码中有"运动".如果监视程序被同一区域调用超过一秒钟或几分钟,它将设置一个易失性布尔值,主线程在下一个检查点读取并终止/重新启动.现在的问题是让任何一个线程同时运行一些.一旦主线程运行,它就不会让看门狗定时器计数正确.因此,我每次调用看门狗时都会考虑屈服(所以它可以计算时间并设置值),但无济于事.使用Thread.sleep(1)而不是Thread.yield()工作.但是我不希望有几个代码区域浪费计算时间,我确信我没有按照它的意图使用它.

这是一个非常简单的示例,说明如何使用Thread.yield().我不明白为什么这里的线程不会切换(它们会在"长时间"和很大程度上不可预测的时间之后切换).请给我一个建议,告诉我如何使这个简单的例子输出ONE和TWO.就像之前写的一样,如果我用sleep(1)切换yield(),它就会像我需要它一样工作(尽管无意义地等待).

    Runnable run1 = new Runnable(){
        public void run(){
            while(true){
                System.out.println("ONE");
                Thread.yield();
            }
        }
    };

    Runnable run2 = new Runnable(){
        public void run(){
            while(true){
                System.out.println("TWO");
                Thread.yield();
            }
        }
    };

    Thread tr1 = new Thread(run1);              
    Thread tr2 = new Thread(run2);

    tr1.start();
    tr2.start();
Run Code Online (Sandbox Code Playgroud)

小智 10

Thread.yield()

这种静态方法主要用于通知系统当前线程愿意"放弃CPU"一段时间.一般的想法是:

线程调度程序将选择要运行的其他线程而不是当前线程.

但是,线程调度程序如何实现让步的细节因平台而异.一般来说,你不应该依赖它以特定的方式行事.不同的事情包括:

在屈服之后,线程将有机会再次运行; 该线程是否放弃其剩余量.

带走是这种行为几乎是可选的,并不能保证实际上确实做任何事情.

你要做的是序列化你的例子中的两个线程的输出并同步你声明的问题中的输出(这是一个不同的问题),这将需要某种锁或互斥锁来阻止第二个线程,直到第一个线程已经完成,哪种方式会破坏并发点,这通常是线程使用的原因.

你真正想要的是一个标志状态的共享数据,第二个线程可以对第一个线程发生变化做出反应.优选地,事件驱动的消息传递模式甚至更容易以同时安全的方式实现.

第二个线程将由第一个线程和一个调用它的方法生成,以递增它所在的块的计数器,您只需使用纯消息传递并传入状态标志Enum或状态更改的其他通知.

什么,你希望做的是做任何类型的轮询.使它成为事件驱动,只让第二个线程始终运行,并检查由父线程设置的实例变量的状态.

  • 整个**并发**的概念是**并发**执行,这意味着同时并行.任何其他东西只是串行执行和线程将使它更复杂,功能更少. (2认同)