Sling Academy
Home/Golang/Timers and Tickers: Managing Time-Based Concurrency in Go

Timers and Tickers: Managing Time-Based Concurrency in Go

Last updated: November 27, 2024

In Go, managing time-based tasks can be efficiently handled using Timers and Tickers. Both are part of the time package and allow developers to control the execution of code based on specific time intervals. Understanding how to effectively use these features can improve the concurrency and scheduling capabilities of your Go applications.

1. Timers in Go

A Timer is used to schedule a piece of code to run after a specified duration. It can be stopped before it triggers, and its channel can be explicitly drained.

Example: Using a Timer

package main

import (
    "fmt"
    "time"
)

func main() {
    timer := time.NewTimer(2 * time.Second)
    fmt.Println("Timer started")

    <-timer.C
    fmt.Println("Timer expired")
}

In the example above, a Timer is set for 2 seconds. Once the time elapses, it sends a signal to the channel timer.C, executing any subsequent code.

Stopping a Timer

You may not always want a Timer to run to completion. You can stop a Timer within Go as shown:

package main

import (
    "fmt"
    "time"
)

func main() {
    timer := time.NewTimer(2 * time.Second)
    go func() {
        fmt.Println("Waiting...")
        <-timer.C
        fmt.Println("Timer expired")
    }()

    timer.Stop()
    fmt.Println("Timer stopped before expiration")
    time.Sleep(3 * time.Second)
}

Here, the Stop() method prevents the Timer from running after it's been activated.

2. Tickers in Go

A Ticker is similar to a Timer, but instead of signaling once, it repeatedly triggers at consistent intervals.

Example: Using a Ticker

package main

import (
    "fmt"
    "time"
)

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

    go func() {
        for {
            select {
            case <-done:
                return
            case t := <-ticker.C:
                fmt.Println("Tick at", t)
            }
        }
    }()

    time.Sleep(5 * time.Second)
    ticker.Stop()
    done <- true
    fmt.Println("Ticker stopped")
}

This code demonstrates a Ticker set to trigger every second. Notice how a channel is used to signal when to stop the Ticker.

Ticker Graceful Shutdown

Signal management is crucial when working with Tickers, ensuring they are stopped properly to prevent resource leaks.

3. Choosing Between Timers and Tickers

Timers are best used for one-time notifications or delaying execution, whereas Tickers are suited for ongoing, periodic intervals. Each serves a distinct purpose, so be sure to choose based on whether your task repeats over time or is a singular event in your concurrent workflow.

Knowing how to manage these two components can greatly enhance your program’s concurrency, making them more effective in handling time-based tasks.

Next Article: Context in Go: Managing Timeouts and Cancellations

Previous Article: Concurrency Patterns: Fan-in and Fan-out in Go

Series: Concurrency and Synchronization in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant