mirror of
https://github.com/xiaoqidun/klock.git
synced 2025-10-11 19:50:24 +08:00
feat(完整功能): 以Apache License 2.0协议开源
This commit is contained in:
142
example_test.go
Normal file
142
example_test.go
Normal file
@@ -0,0 +1,142 @@
|
||||
// Copyright 2025 肖其顿
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package klock_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xiaoqidun/klock"
|
||||
)
|
||||
|
||||
// ExampleKeyLock_Lock 演示了如何使用 Lock 和 Unlock 来保护对共享资源的并发写操作。
|
||||
func ExampleKeyLock_Lock() {
|
||||
kl := klock.New()
|
||||
var wg sync.WaitGroup
|
||||
// 共享数据
|
||||
sharedData := make(map[string]int)
|
||||
// 模拟10个并发请求更新同一个键的值
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
// 为 "dataKey" 加锁,确保同一时间只有一个 goroutine 能修改其值
|
||||
kl.Lock("dataKey")
|
||||
sharedData["dataKey"]++
|
||||
kl.Unlock("dataKey")
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
fmt.Printf("键 'dataKey' 的最终计数值是: %d\n", sharedData["dataKey"])
|
||||
// Output: 键 'dataKey' 的最终计数值是: 10
|
||||
}
|
||||
|
||||
// ExampleKeyLock_RLock 演示了多个 goroutine 如何同时获取读锁以并发地读取数据。
|
||||
func ExampleKeyLock_RLock() {
|
||||
kl := klock.New()
|
||||
sharedResource := "这是一个共享资源"
|
||||
// 启动5个 goroutine 并发读取数据
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < 5; i++ {
|
||||
wg.Add(1)
|
||||
go func(gid int) {
|
||||
defer wg.Done()
|
||||
kl.RLock("resourceKey")
|
||||
fmt.Printf("Goroutine %d 读取资源: %s\n", gid, sharedResource)
|
||||
kl.RUnlock("resourceKey")
|
||||
}(i)
|
||||
}
|
||||
wg.Wait()
|
||||
// 注意:由于 goroutine 调度顺序不确定,输出的顺序可能不同。
|
||||
// 但这个示例的核心是展示它们可以并发执行,而不会像写锁一样互相等待。
|
||||
}
|
||||
|
||||
// ExampleKeyLock_TryLock 演示了如何尝试非阻塞地获取锁。
|
||||
// 如果锁已被占用,它不会等待,而是立即返回 false。
|
||||
func ExampleKeyLock_TryLock() {
|
||||
kl := klock.New()
|
||||
key := "resource_key"
|
||||
// 第一次尝试,应该成功
|
||||
if kl.TryLock(key) {
|
||||
fmt.Println("第一次 TryLock 成功获取锁")
|
||||
// 第二次尝试,因为锁已被持有,所以应该失败
|
||||
if !kl.TryLock(key) {
|
||||
fmt.Println("第二次 TryLock 失败,因为锁已被占用")
|
||||
}
|
||||
kl.Unlock(key)
|
||||
}
|
||||
// Output:
|
||||
// 第一次 TryLock 成功获取锁
|
||||
// 第二次 TryLock 失败,因为锁已被占用
|
||||
}
|
||||
|
||||
// ExampleKeyLock_LockWithTimeout 演示了如何在指定时间内尝试获取锁,避免无限期等待。
|
||||
func ExampleKeyLock_LockWithTimeout() {
|
||||
kl := klock.New()
|
||||
key := "task_key"
|
||||
// 主 goroutine 先获取锁
|
||||
kl.Lock(key)
|
||||
fmt.Println("主 goroutine 持有锁")
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
// 尝试在 10ms 内获取锁,此时主 goroutine 仍持有锁,所以会失败
|
||||
fmt.Println("Goroutine 尝试在 10ms 内获取锁...")
|
||||
if !kl.LockWithTimeout(key, 10*time.Millisecond) {
|
||||
fmt.Println("Goroutine 获取锁超时,任务取消")
|
||||
}
|
||||
}()
|
||||
// 等待 20ms 后释放锁
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
kl.Unlock(key)
|
||||
fmt.Println("主 goroutine 释放锁")
|
||||
wg.Wait()
|
||||
// Output:
|
||||
// 主 goroutine 持有锁
|
||||
// Goroutine 尝试在 10ms 内获取锁...
|
||||
// Goroutine 获取锁超时,任务取消
|
||||
// 主 goroutine 释放锁
|
||||
}
|
||||
|
||||
// ExampleKeyLock_Status 演示了如何查询一个键的当前锁定状态。
|
||||
func ExampleKeyLock_Status() {
|
||||
kl := klock.New()
|
||||
key := "status_key"
|
||||
var wg sync.WaitGroup
|
||||
kl.Lock(key)
|
||||
// 启动两个 goroutine 在后台等待锁
|
||||
for i := 0; i < 2; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
kl.Lock(key)
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
kl.Unlock(key)
|
||||
}()
|
||||
}
|
||||
// 等待一小段时间,确保两个 goroutine 已经处于等待状态
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
holders, waiters := kl.Status(key)
|
||||
fmt.Printf("当前持有者: %d, 等待者: %d\n", holders, waiters)
|
||||
kl.Unlock(key)
|
||||
wg.Wait()
|
||||
holders, waiters = kl.Status(key)
|
||||
fmt.Printf("所有任务完成后,持有者: %d, 等待者: %d\n", holders, waiters)
|
||||
// Output:
|
||||
// 当前持有者: 1, 等待者: 2
|
||||
// 所有任务完成后,持有者: 0, 等待者: 0
|
||||
}
|
Reference in New Issue
Block a user