唤醒了沉睡的线程 - 中断()与"分裂"睡眠分为多个睡觉 [英] Waking up a sleeping thread - interrupt() versus "splitting" the sleep into multiple sleeps

查看:307
本文介绍了唤醒了沉睡的线程 - 中断()与"分裂"睡眠分为多个睡觉的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这要求上来在我的Andr​​oid应用程序,但它适用于Java的一般。我的应用做了每隔几秒钟。我已经实现了这个原则(只是相关片段 - 不是一个完整的code):

This requirement came up in my Android app, but it applies to Java in general. My app "does something" every few seconds. I have implemented this as follows (just relevant snippets - not a complete code):

Snippet1:

public class PeriodicTask {

    private boolean running = true;
    private int interval = 5;

    public void startTask(){
        while (running){
            doSomething();
            try{
                Thread.sleep(interval * 1000);
            } catch(InterruptedException e){
                //Handle the exception.
            }
        }
    }

    public void stopTask(){
        this.running = false;
    }

    public void setInterval(int newInterval){
        this.interval = newInterval;
    }
}

使用这种方法的问题,正如你所看到的,是的setInterval()是不是立即生效。只需经过previous睡眠的功效()已完成。

The problem with this approach, as you can see, is that setInterval() is not immediately effective. It takes effect only after a previous sleep() has completed.

由于我的用例允许终端用户设置在固定步骤的时间间隔(1秒 - 从1到60秒),我修改实施一个循环内入睡;并检查新的区间值每秒如下:

Since my use case allows the end user to set the interval in fixed steps (of 1 second - from 1 to 60 seconds), I modified the implementation to sleep within a loop; and check for the new interval value every second as follows:

Snippet2:

public class PeriodicTask {

    private boolean running = true;
    private int interval = 5;
    private int loopCounter = 0;

    public void startTask(){
        while (running){
            doSomething();
            try{
                while(loopCounter < interval) {
                    Thread.sleep(1 * 1000);
                    loopCounter ++;
                }
            } catch(InterruptedException e){
                //Handle the exception.
            }
        }
    }

    public void stopTask(){
        this.running = false;
    }

    public void setInterval(int newInterval){
        synchronized (this) {
            this.interval = newInterval;
            if(newInterval < loopCounter){
                loopCounter = 0;
            }
        }
    }
}

有没有理由不使用这种方法?

Is there a reason to not use this approach?

我最近遇到了中断()的方法达到此目的。但是,我不能完全弄清楚如何使用它。其一,中断方法,不同于睡眠方法不是静态。那么,是什么做我打断?

I recently came across the interrupt() method for this purpose. But, I couldn't exactly figure out how to use it. For one, the interrupt method, unlike the sleep method is not static. So, what Thread do I interrupt?

public void setInterval(int newInterval){
        this.interval = newInterval;
        //What thread do I call interrupt() on?
    }

其次,如果我成功地打断睡眠,我相信块的 InterruptedException的将被执行。不过,我需要再次调用 startTask()在这一点上。我很困惑关于这个递归的终止。我已经经历了几个问题转眼就SO关于使用中断(),但无法找出任何可以帮助我。

Secondly, if I do succeed in interrupting the sleeping Thread, I believe the catch block for the InterruptedException will be executed. However, I will need to call the startTask() again at this point. I am confused regarding the termination of this recursion. I have gone through several questions on SO regarding the use of interrupt(), but couldn't figure out anything that helps me.

任何指针?

我的应用程序获取使用REST调用每隔几秒一些值。更新间隔是可配置的用户。

MY app fetches some values using a REST call every few seconds. The update interval is configurable by the user.

现在,假设在更新间隔已被设置为60秒。 Snippet1我贴会的工作(不正确地)如下:

Now, say the update interval has been set to 60 seconds. Snippet1 I posted would work (incorrectly) as follows:

  • 线程进入睡眠状态,持续60秒。
  • 现在,让我们看看吧用户更改更新时间间隔为5秒。线程还在睡觉。
  • PeriodicTask 将看到60秒只到期后的新的更新间隔。
  • Thread goes to sleep for 60 seconds.
  • Now, lets say user changes the update interval to 5 seconds. The thread is still sleeping.
  • The PeriodicTask would see the new update interval only after the 60 seconds have expired.

确切的要求是,新的更新间隔应(被设置后,或至少不晚于1秒 - 因为这是用户很可能无论如何感知),立即生效。

The exact requirement is that the new update intervals should be effective immediately (or at least no later than 1 second after being set - since that is what the user is likely to perceive anyway).

我的Snippet2和Snippet3是实现这一要求的企图。

My Snippet2 and Snippet3 are attempts at achieving this requirement.

推荐答案

IIRC,在Java中,你可以的Object.wait(),并带有超时。这是不是你想要的?如果你想从另一个线程更改超时,改变一些waitValue'变量和notify()。线程将立即运行,然后再等待新的超时值。没有明确的睡眠要求。

IIRC, in Java you can object.wait() with a timeout. Is this not what you want? If you want to change the timeout from another thread, change some 'waitValue' variable and notify(). The thread will then 'immediately' run and then wait again with the new timeout value. No explicit sleep required.

这篇关于唤醒了沉睡的线程 - 中断()与&QUOT;分裂&QUOT;睡眠分为多个睡觉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆