MST

星途 面试题库

面试题:Go语言time包定时器在高并发场景下的资源优化

在一个高并发的Go程序中,有大量的time.Timer定时器被创建和销毁,如何优化资源的使用,避免内存泄漏和性能瓶颈?请描述具体的优化思路,并给出关键代码示例。
26.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

优化思路

  1. 复用Timer:避免频繁创建和销毁time.Timer,使用time.Timer池来复用已有的Timer实例。
  2. 及时停止Timer:确保在不再需要Timer时,及时调用Stop方法停止定时器,避免其继续运行造成资源浪费。
  3. 优化调度逻辑:合理安排定时器触发的任务,减少不必要的定时器使用。

关键代码示例

package main

import (
    "container/list"
    "fmt"
    "sync"
    "time"
)

// TimerPool 定义定时器池
type TimerPool struct {
    sync.Mutex
    pool *list.List
}

// NewTimerPool 创建新的定时器池
func NewTimerPool() *TimerPool {
    return &TimerPool{
        pool: list.New(),
    }
}

// Get 从池中获取一个定时器
func (tp *TimerPool) Get() *time.Timer {
    tp.Lock()
    defer tp.Unlock()
    if tp.pool.Len() > 0 {
        e := tp.pool.Front()
        t := e.Value.(*time.Timer)
        tp.pool.Remove(e)
        return t
    }
    return time.NewTimer(0)
}

// Put 将定时器放回池中
func (tp *TimerPool) Put(t *time.Timer) {
    tp.Lock()
    defer tp.Unlock()
    t.Reset(0)
    tp.pool.PushBack(t)
}

func main() {
    timerPool := NewTimerPool()

    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            timer := timerPool.Get()
            select {
            case <-timer.C:
            case <-time.After(2 * time.Second):
            }
            timerPool.Put(timer)
        }()
    }
    wg.Wait()
}

在上述代码中:

  1. 定义了TimerPool结构体用于管理time.Timer的池,使用sync.Mutex进行并发安全控制。
  2. NewTimerPool函数用于初始化定时器池。
  3. Get方法从池中获取一个time.Timer,如果池中没有则创建新的。
  4. Put方法将time.Timer放回池中,并重置定时器。
  5. main函数中模拟了高并发场景下定时器的获取和放回操作。