Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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 对象的elapsedRealtime模拟。等待_Java_Android_Multithreading_Wait_Notify - Fatal编程技术网

Java 对象的elapsedRealtime模拟。等待

Java 对象的elapsedRealtime模拟。等待,java,android,multithreading,wait,notify,Java,Android,Multithreading,Wait,Notify,我在android应用程序服务中使用了Object.wait(timeout)。但它不计算在“深度睡眠模式”中花费的时间。我使用AlarmManager定期唤醒我的应用程序,所以从深度睡眠中醒来不是问题。问题是wait(60000)在深度睡眠100秒后不会终止 正如我在帮助页面上读到的,object.wait使用方法,在深度睡眠时停止计数。为了我的需要,最好使用它 如何实现类似于Object.wait(timeout)但使用方法?或者我可以用什么来代替 我使用此方法的任务之一是在一段时间内没有

我在android应用程序服务中使用了
Object.wait(timeout)
。但它不计算在“深度睡眠模式”中花费的时间。我使用AlarmManager定期唤醒我的应用程序,所以从深度睡眠中醒来不是问题。问题是
wait(60000)
在深度睡眠100秒后不会终止

正如我在帮助页面上读到的,
object.wait
使用方法,在深度睡眠时停止计数。为了我的需要,最好使用它

如何实现类似于
Object.wait(timeout)
但使用方法?或者我可以用什么来代替


我使用此方法的任务之一是在一段时间内没有其他数据包在队列中时生成“ping”数据包以通过网络发送。

您在评论中提到的
interrupt()
导致终止(杀死)线程,但这是完全错误的,它只是向等待/加入/休眠线程抛出一个异常。

public void Foo implements Runnable{
  public void run(){
   //do some work
   try{Thread.sleep(10000);}catch(Exception ex){/*when thread got interrupted*/}
   //do something else
  }
}

问题就在这里,因为您将所有业务放在
try
块中,因此中断会导致代码跳转到
catch
块中,在该块之后没有任何业务,因此这不是线程问题。

我建议您使用以下任何一种方法,而不是使用普通对象.wait()或thread.sleep()

  • 使用java.util.concurrent.newScheduledThreadPool,它使您能够以固定的时间间隔或延迟安排任务。使用threadCount=1初始化线程池将提供一个线程

  • 使用java.util.Timer,它允许您计划TimerTask

  • 我认为1。是首选的方法

    如果您有特定的要求,希望插入计时器对象或使用特定的或第三方计时提供程序,那么您需要做的是编写自己的计划程序来包装ScheduledExecutorService,然后使用自己的计时器转换时间或从自己的计时器获取时间。基本上,您可以使用自己的时间计算在包装服务上启动计划任务

    在我的actor模型中有一个这样的调度器示例,如下所示。看看这个包中的DefaultScheduler。它可能有点问题(我还没有完全测试过),但它应该会给你一个好主意


    不确定它是否完全符合您的要求,但我写这篇文章是为了暂停一段时间,但让其他线程过早地唤醒我

    它在内部使用
    阻塞队列
    来执行睡眠操作,因此它避免使用
    睡眠
    等待
    以及随之而来的所有悲伤

    不确定它在Android下会如何运行,我不使用它,但我怀疑您现有的
    AlarmManager
    工作将适应

    /**
     * Use one of these to doze for a certain time.
     *
     * The dozing is fully interruptable.
     *
     * Another thread can stop the caller's doze with either a wakeup call or an abort call.
     *
     * These can be interpreted in any way you like but it is intended that a Wakeup is
     * interpreted as a normal awakening and should probably be treated in exactly the
     * same way as an Alarm. An Abort should probably be interpreted as a suggestion
     * to abandon the process.
     */
    public class Doze {
      // Special alarm messages.
      public enum Alarm {
        // Standard timeout.
        Alarm,
        // Forced wake from your doze.
        Wakeup,
        // Abort the whole Doze process.
        Abort;
      }
      // My queue to wait on.
      private final BlockingQueue<Alarm> doze = new ArrayBlockingQueue<>(1);
      // How long to wait by default.
      private final long wait;
    
      public Doze(long wait) {
        this.wait = wait;
      }
    
      public Doze() {
        this(0);
      }
    
      public Alarm doze() throws InterruptedException {
        // Wait that long.
        return doze(wait);
      }
    
      public Alarm doze(long wait) throws InterruptedException {
        // Wait that long.
        Alarm poll = doze.poll(wait, TimeUnit.MILLISECONDS);
        // If we got nothing then it must be a normal wakeup.
        return poll == null ? Alarm.Alarm : poll;
      }
    
      public void wakeup() {
        // Just post a Wakeup.
        doze.add(Alarm.Wakeup);
      }
    
      public void abort() {
        // Signal the system to abort.
        doze.add(Alarm.Abort);
      }
    
      private static long elapsed ( long start ) {
        return System.currentTimeMillis() - start;
      }
    
      // Test code.
      public static void main(String[] args) throws InterruptedException {
        // Doze for 1 second at a time.
        final Doze d = new Doze(1 * 1000);
        final long start = System.currentTimeMillis();
    
        // Start a dozing thread.
        new Thread(new Runnable() {
          @Override
          public void run() {
            try {
              Alarm a = d.doze();
              // Wait forever until we are aborted.
              while (a != Alarm.Abort) {
                System.out.println(elapsed(start) + ": Doze returned " + a);
                a = d.doze();
              }
              System.out.println(elapsed(start) + ": Doze returned " + a);
            } catch (InterruptedException ex) {
              // Just exit on interrupt.
            }
          }
    
        }).start();
    
    
        // Wait for a few seconds.
        Thread.sleep(3210);
    
        // Wake it up.
        d.wakeup();
    
        // Wait for a few seconds.
        Thread.sleep(4321);
    
        // Abort it.
        d.abort();
    
    
      }
    
    }
    
    /**
    *用其中一个来打一段时间的盹。
    *
    *打瞌睡完全可以中断。
    *
    *另一个线程可以通过唤醒调用或中止调用来停止调用方的睡眠。
    *
    *这些可以用你喜欢的任何方式来解释,但它的目的是唤醒
    *被解释为正常的觉醒,可能应该以正确的方式进行治疗
    *和闹钟一样。中止可能应解释为一种建议
    *放弃这个过程。
    */
    公共课打瞌睡{
    //特别警报信息。
    公共枚举报警{
    //标准超时。
    警报,
    //强迫你从睡梦中醒来。
    醒醒,
    //中止整个打盹过程。
    中止
    }
    //我要排队等候。
    private final BlockingQueue doze=new ArrayBlockingQueue(1);
    //默认情况下等待多长时间。
    私人最后长时间等待;
    公众打盹(长时间等待){
    this.wait=等待;
    }
    打瞌睡{
    这(0);
    }
    public Alarm doze()抛出InterruptedException{
    //等那么久。
    回瞌睡(等待);
    }
    公共报警休眠(长等待)引发中断异常{
    //等那么久。
    报警轮询=doze.poll(等待,时间单位为毫秒);
    //如果我们什么都没有,那一定是正常的醒来。
    返回轮询==null?报警。报警:轮询;
    }
    公共无效唤醒(){
    //只需发布一个唤醒。
    doze.add(Alarm.Wakeup);
    }
    公共无效中止(){
    //向系统发出中止信号。
    添加(报警、中止);
    }
    专用静态长时间运行(长时间启动){
    返回系统.currentTimeMillis()-开始;
    }
    //测试代码。
    公共静态void main(字符串[]args)引发InterruptedException{
    //一次打一秒钟盹。
    最终打瞌睡d=新打瞌睡(1*1000);
    最终长启动=System.currentTimeMillis();
    //开始打瞌睡。
    新线程(newrunnable()){
    @凌驾
    公开募捐{
    试一试{
    报警a=d.打瞌睡();
    //永远等待,直到我们流产。
    while(a!=报警。中止){
    System.out.println(经过(开始)+“:打瞌睡返回”+a);
    a=d.打瞌睡();
    }
    System.out.println(经过(开始)+“:打瞌睡返回”+a);
    }捕获(中断异常例外){
    //只要中断就退出。
    }
    }
    }).start();
    //等几秒钟。
    睡眠(3210);
    //醒醒。
    d、 唤醒();
    //等几秒钟。
    睡眠(4321);
    //中止它。
    d、 中止();
    }
    }
    
    那么为什么要等待()睡觉呢?对于睡眠来说,进入睡眠(),睡眠和等待之间有很大的区别,你愿意分享你的代码吗?!我使用
    wait
    是因为我想在调用
    notify
    时停止等待。不管怎么说,
    sleep
    也有同样的问题。你就快到了。您已经在使用AlarmManager-为什么不全部使用它而不是等待/睡眠?您可以中断线程以跳过剩余的空闲时间睡眠,等待/通知旨在同步线程,并尝试睡眠10000次,共6次。@Pescis,因为我有多个线程用于多个simultaniuos目的。我使用许多等待调用,并从其他线程使用notify。我将尝试从AlarmManager中调用notify(通知),如果timeo