Java 如何更改线程的持续时间。sleep()已处于睡眠状态

Java 如何更改线程的持续时间。sleep()已处于睡眠状态,java,multithreading,Java,Multithreading,我正在寻找关于在睡眠中改变睡眠模式的信息。基本上这就是我的处境 public void run() { while(running) { //Update Stuff... try { long time = System.currentTimeMillis() + interval; String dateFormatted = new SimpleDateFormat("yyyy/MM/dd HH:mm:

我正在寻找关于在睡眠中改变睡眠模式的信息。基本上这就是我的处境

public void run() {
    while(running) {
        //Update Stuff...
        try {
            long time = System.currentTimeMillis() + interval;
            String dateFormatted = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss a").format(new Date(time));
            Thread.sleep(interval);
        } catch (InterruptedException e) {
            //Handle Errors...
        }
    }
}
因此,我所做的是在程序启动时,它将需要时间间隔(目前为60000),但是GUI有能够更改时间间隔的选项(例如1小时、2小时、3小时等)。我可以从GUI中很好地更新并更改间隔变量

但是,当我更改它时,线程仍处于休眠状态,将等待它完成,并在下一次迭代中更新。中断当前休眠线程(或唤醒它)的最佳方法是什么。此外,我还担心它是否“安全”,因为它将在生产服务器上运行


任何方向/指导都是非常棒的。

我不会选择interrupt(),更像是分割睡眠,让我们假设1分钟,然后检查是该起床还是再次睡觉。在这种情况下,开销几乎为零。

您可以通过
等待
/
通知
实现一个简单的解决方案

大概是这样的:

class DurationSleeper {

    private final Object monitor = new Object();
    private long durationMillis = 0;

    public DurationSleeper(long duration, TimeUnit timeUnit) {
        setDuration(duration, timeUnit);
    }

    public void sleep() {
        long millisSlept = 0;

        while (true) {
            synchronized (monitor) {
                try {
                    long millisToSleep = durationMillis - millisSlept;
                    if (millisToSleep <= 0) {
                        return;
                    }
                    long sleepStartedInNanos = System.nanoTime(); // Not using System.currentTimeMillis - it depends on OS time, and may be changed at any moment (e.g. by daylight saving time)
                    monitor.wait(millisToSleep);
                    millisSlept += TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - sleepStartedInNanos);
                } catch (InterruptedException e) {
                    throw new RuntimeException("Execution interrupted.", e);
                }
            }
        }
    }

    public void setDuration(long newDuration, TimeUnit timeUnit) {
        synchronized (monitor) {
            this.durationMillis = timeUnit.toMillis(newDuration);
            monitor.notifyAll();
        }
    }
}
class持续时间{
私有最终对象监视器=新对象();
私有长持续时间毫秒=0;
公共持续时间睡眠者(长持续时间,时间单位){
设置持续时间(持续时间,时间单位);
}
公众睡眠{
长毫细=0;
while(true){
同步(监视器){
试一试{
长毫秒睡眠=持续毫秒-毫秒睡眠;

如果(millisToSleep中断来自gui,捕获线程中的中断,使用新值开始睡眠中断,对我来说,这似乎是最干净的答案。顺便说一句,您的注释
//处理错误…
是错误的;中断不是错误。您需要更改睡眠持续时间,还是只需调用另一个线程即可。sleep(另一个区间)在原来的时间间隔之后?我正在更改下一个睡眠持续时间-但希望唤醒它并再次运行进程。例如,每次它更改时间间隔时,基本函数都会再次运行,然后为新的时间间隔而睡眠。与其调用
sleep
,不如使用定时等待来发出信号。当您更改时间间隔时leep时间,给它等待的物体发信号,让它从睡眠中醒来。