如何在Go中定期安排任务?

25

在Go语言中,是否有类似Java本地库ScheduledExecutorService的本地库或第三方支持可用于生产环境?

请查看Java 1.8中的代码片段:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class TaskScheduler {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Runnable runnable = ()-> {
                // task to run goes here
                System.out.println("Hello !!");
        };
        ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
        service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);

    }

}

每隔一秒钟它将打印Hello !!


1
我在Go语言中找到了一些使用定时器的实现,但对于实际应用场景不满意。我们需要更多的解释,为什么你不满意。 - novalagung
需要一个例程池来执行每个例程的任务,且不会有内存泄漏 :) @xpare - Siddhanta Rath
2
我认为需要一组例程的情况听起来像是go routine可以解决的。设置一个计时器并在完成后停止它不会泄漏内存。 - poy
1个回答

37

不需要使用第三方库来实现这个功能。只需利用goroutine的优势,并使用time包中提供的可用time.Sleep() API,就可以达到同样的效果。

例如:

go func() {
    for true {
        fmt.Println("Hello !!")
        time.Sleep(1 * time.Second)
    }
}()

游乐场:https://play.golang.org/p/IMV_IAt-VQX


使用ticker的示例1

根据Siddhanta的建议,这里提供一个示例,通过使用ticker实现相同的结果(取自ticker的go文档页面,根据您的要求进行了一些修改)。

done := make(chan bool)
ticker := time.NewTicker(1 * time.Second)

go func() {
    for {
        select {
        case <-done:
            ticker.Stop()
            return
        case <-ticker.C:
            fmt.Println("Hello !!")
        }
    }
}()

// wait for 10 seconds
time.Sleep(10 *time.Second)
done <- true

可以从 ticker.C 通道中获取计时器时间信息(即执行 Hello !! 的时间)。

case t := <-ticker.C:
    fmt.Println(t)

游乐场:https://play.golang.org/p/TN2M-AMr39L


使用ticker的示例 #2

另一个简化的ticker示例,来自https://gobyexample.com/tickers

ticker := time.NewTicker(1 * time.Second)
go func() {
    for range ticker.C {
        fmt.Println("Hello !!")
    }
}()

// wait for 10 seconds
time.Sleep(10 *time.Second)
ticker.Stop()

4
最好使用 time.Ticker - Ullaakut
1
你不需要 for true {},只需要 for {} - iBug
如果您根本不停止计时器会发生什么? - Glyphack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接