go语言生成雪花算法代码
时间: 2023-10-25 21:10:17 浏览: 45
下面是一个简单的 Go 代码示例,用于生成雪花算法的 ID:
```go
package main
import (
"fmt"
"sync"
"time"
)
const (
workerBits uint8 = 10
sequenceBits uint8 = 12
maxWorkerID int64 = -1 ^ (-1 << workerBits)
maxSequence int64 = -1 ^ (-1 << sequenceBits)
epoch int64 = 1600000000000 // 2020-09-13 00:00:00 UTC
)
type Snowflake struct {
mutex sync.Mutex
lastTimestamp int64
workerID int64
sequence int64
}
func NewSnowflake(workerID int64) *Snowflake {
if workerID < 0 || workerID > maxWorkerID {
panic(fmt.Sprintf("worker ID must be between 0 and %d", maxWorkerID))
}
return &Snowflake{
lastTimestamp: 0,
workerID: workerID,
sequence: 0,
}
}
func (sf *Snowflake) NextID() int64 {
sf.mutex.Lock()
defer sf.mutex.Unlock()
now := time.Now().UnixNano() / 1000000 // convert to milliseconds
if now < sf.lastTimestamp {
panic(fmt.Sprintf("clock moved backwards, refusing to generate ID for %d milliseconds", sf.lastTimestamp-now))
}
if now == sf.lastTimestamp {
sf.sequence = (sf.sequence + 1) & maxSequence
if sf.sequence == 0 {
now = sf.waitNextMillisecond(now)
}
} else {
sf.sequence = 0
}
sf.lastTimestamp = now
return (now-epoch) << (workerBits+sequenceBits) | sf.workerID << sequenceBits | sf.sequence
}
func (sf *Snowflake) waitNextMillisecond(currentTimestamp int64) int64 {
for {
now := time.Now().UnixNano() / 1000000
if now > currentTimestamp {
return now
}
}
}
func main() {
sf := NewSnowflake(1)
for i := 0; i < 10; i++ {
fmt.Println(sf.NextID())
}
}
```
该代码使用了互斥锁来防止多个 Goroutine 同时生成相同的 ID。它还实现了一个等待下一个毫秒的函数,以防止在同一毫秒内生成多个 ID。您可以根据自己的需求调整 workerBits 和 sequenceBits 变量的值。