Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
纯Java:如何知道线程是否处于休眠状态?_Java_Multithreading_Synchronized - Fatal编程技术网

纯Java:如何知道线程是否处于休眠状态?

纯Java:如何知道线程是否处于休眠状态?,java,multithreading,synchronized,Java,Multithreading,Synchronized,我有一条线可以做几件事。其中之一就是睡一段时间。 正常睡眠后,它调用delayFinished()方法,但如果睡眠被中断,则不应调用delayFinished()。我还需要一个中止睡眠的方法,其他线程可能会调用该方法 因此,这是一个符合我意图的实现,但我认为它不会起作用: public class MyThread extends Thread { private boolean sleeping=false; private Object sleepingControl=new O

我有一条线可以做几件事。其中之一就是睡一段时间。 正常睡眠后,它调用
delayFinished()
方法,但如果睡眠被中断,则不应调用
delayFinished()
。我还需要一个中止睡眠的方法,其他线程可能会调用该方法

因此,这是一个符合我意图的实现,但我认为它不会起作用:

public class MyThread extends Thread {
   private boolean sleeping=false;
   private Object sleepingControl=new Object();

   //... other unrelated stuff...

   private void delay() {
      try {
          synchronized(sleepingControl) {
             sleeping=true;         
             sleep(delay);
             sleeping=false;                        
             delayFinished();
          }
      } catch (InterruptedException e) {
          sleeping=false;
      }
    }
    public void abortDelay() {
          synchronized(sleepingControl) {
             if (sleeping)          
                interrupt();
          }
    }
 }
如果调用了
delay()
,并且当它处于睡眠状态时,
abortDelay()
被另一个线程(主要用例)调用,
abortDelay()
将挂起synchronized语句,因为
delay()
的调用方拥有该监视器,并且尚未放弃它

另一方面,如果以这种方式实施延迟:

   private void delay() {
      synchronized(sleepingControl) {
         sleeping=true;         
      }
      try {              
             sleep(delay);
有可能调用
delay()
,完成同步块设置 休眠为true,但随后调用
abortDelay()
,它将调用
interrupt()
即使线程尚未开始睡眠


有人能对这些尝试提出改进意见吗?

您需要调查Object.wait()/notify()而不是使用sleep()。使用wait()最关键的一点是,它在等待时释放对象上的锁,允许另一个线程获取锁并使用notify()将其唤醒

e、 g

这也不是全部,因为wait()有一个奇怪的实现怪癖,它可能会被错误地唤醒。因此,您需要手动循环wait()调用,如果它返回,请检查时间是否已过期


实际上,我认为通过
java.util.concurrent
类可以实现上述更简单的功能。看看
Lock
类。

Mike Q.的答案就是你想要的答案。但要使代码正常工作,请使
睡眠
不稳定,并从
中止延迟
中删除同步。那么您唯一的问题就是
abortDelay
可能会在任何一行
sleep=false之前捕获
delay
。因此,在两行之后,调用
interrupted()
以清除可能的设置

更正/细化:
abortDelay
需要同步。代码应该如下所示:

private final Object     sleepingControl = new Object();
private volatile boolean sleeping;

private void delay() {
    try {
        sleeping=true;  // Synching not needed.
        sleep(delay);
        // Thread COULD be interrupted at this point!
        // Now makes sure abortDelay sees this change.
        synchronized (sleepingControl)  {
            sleeping = false;
            // Thread can no longer be interrupted.
            // Clear flag if it is set.
            interrupted();
        }
        delayFinished();
    }
    catch (InterruptedException e) {
        // Thread COULD be interrupted at this point!
        synchronized (sleepingControl)  {
            sleeping = false;
            // Thread can no longer be interrupted.
            // Clear flag if it is set.
            interrupted();
        }
    }
}
public void abortDelay() {
    synchronized (sleepingControl)  {
        if (sleeping)
            // At this point, "sleeping" HAS to be true.
            interrupt();
    }
} 

“同步”的东西有必要吗?“wait()有一个奇怪的实现怪癖,它可能会被错误地唤醒”-我怀疑只有在同步初始活动无法正常工作的操作系统上。如果您多次调用delay()(从类中的任何位置),使用abortDelay()知道哪些调用应该中止可能会有问题method@Martin,如果没有已同步的,则无法使用“等待/通知”。你会得到一份工作的IllegalMonitorStateException@Martin我不知道,但有文件记载,所以我们必须解释其中一件事:)拉尔夫,你的答案不清楚。特别是你所说的“在任何一行之前…”但是:如果我从abortDelay中删除同步,那么将它保持在delay()中有什么意义呢?另外,我不确定“在两行之后调用interrupt()”是什么意思,但我认为如果在线程不可中断(不是在睡眠中)的情况下调用interrupt(),这是一个问题。因此,在没有“synchronized”的情况下,如果在sleep()之前或之后调用abortDelay(),则会出现问题。如果你认为你有一个很好的修复我的代码,请张贴固定的代码。我会感兴趣的。thanks@inor:我的同步删除错误;您确实需要在
abortDelay
中使用它们。我将编辑我的答案,以包含我认为正确的解决方案。你总是可以打断一个线程;它只是树立了一面旗帜<代码>睡眠
看到您已经这样做并抛出异常。如果在调用
sleep
后线程被“中断”,则需要调用
interrupted
来清除它。我最初的建议是,如果abortDelay线程被选中
sleep
,被暂停半个小时,然后被调用
interrupt
,则可以随时中断线程。不太好。@inor:我想证明你的解决方案是可行的。使用wait-modify是处理此问题的标准方法。
private final Object     sleepingControl = new Object();
private volatile boolean sleeping;

private void delay() {
    try {
        sleeping=true;  // Synching not needed.
        sleep(delay);
        // Thread COULD be interrupted at this point!
        // Now makes sure abortDelay sees this change.
        synchronized (sleepingControl)  {
            sleeping = false;
            // Thread can no longer be interrupted.
            // Clear flag if it is set.
            interrupted();
        }
        delayFinished();
    }
    catch (InterruptedException e) {
        // Thread COULD be interrupted at this point!
        synchronized (sleepingControl)  {
            sleeping = false;
            // Thread can no longer be interrupted.
            // Clear flag if it is set.
            interrupted();
        }
    }
}
public void abortDelay() {
    synchronized (sleepingControl)  {
        if (sleeping)
            // At this point, "sleeping" HAS to be true.
            interrupt();
    }
}