155 lines
3.4 KiB
Plaintext
155 lines
3.4 KiB
Plaintext
|
|
package syncUtil
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestRWNewLocker1(t *testing.T) {
|
||
|
|
count := 1000000
|
||
|
|
succeedCount := 0
|
||
|
|
expected := 1000000
|
||
|
|
goroutineCount := 1
|
||
|
|
|
||
|
|
lockerObj := NewRWLocker()
|
||
|
|
ch := make(chan bool, goroutineCount)
|
||
|
|
|
||
|
|
for i := 0; i < goroutineCount; i++ {
|
||
|
|
go rwLockerTest(lockerObj, &succeedCount, count/goroutineCount, ch)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < goroutineCount; i++ {
|
||
|
|
<-ch
|
||
|
|
}
|
||
|
|
|
||
|
|
if succeedCount != expected {
|
||
|
|
t.Errorf("Expected %d, but got %d", expected, succeedCount)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRWNewLocker2(t *testing.T) {
|
||
|
|
count := 1000000
|
||
|
|
succeedCount := 0
|
||
|
|
expected := 1000000
|
||
|
|
goroutineCount := 100
|
||
|
|
|
||
|
|
lockerObj := NewRWLocker()
|
||
|
|
ch := make(chan bool, goroutineCount)
|
||
|
|
|
||
|
|
for i := 0; i < goroutineCount; i++ {
|
||
|
|
go rwLockerTest(lockerObj, &succeedCount, count/goroutineCount, ch)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < goroutineCount; i++ {
|
||
|
|
<-ch
|
||
|
|
}
|
||
|
|
|
||
|
|
if succeedCount != expected {
|
||
|
|
t.Errorf("Expected %d, but got %d", expected, succeedCount)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRWNewLocker3(t *testing.T) {
|
||
|
|
count := 1000000
|
||
|
|
succeedCount := 0
|
||
|
|
expected := 1000000
|
||
|
|
goroutineCount := 10000
|
||
|
|
|
||
|
|
lockerObj := NewRWLocker()
|
||
|
|
ch := make(chan bool, goroutineCount)
|
||
|
|
|
||
|
|
for i := 0; i < goroutineCount; i++ {
|
||
|
|
go rwLockerTest(lockerObj, &succeedCount, count/goroutineCount, ch)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < goroutineCount; i++ {
|
||
|
|
<-ch
|
||
|
|
}
|
||
|
|
|
||
|
|
if succeedCount != expected {
|
||
|
|
t.Errorf("Expected %d, but got %d", expected, succeedCount)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRWNewLocker4(t *testing.T) {
|
||
|
|
lockerObj := NewRWLocker()
|
||
|
|
if successful, _, _ := lockerObj.RLock(100); successful == false {
|
||
|
|
t.Errorf("It should be successful to get a read lock, but now it fails.")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if successful, _, _ := lockerObj.RLock(100); successful == false {
|
||
|
|
t.Errorf("It should be successful to get a read lock, but now it fails.")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if successful, _, _ := lockerObj.RLock(100); successful == false {
|
||
|
|
t.Errorf("It should be successful to get a read lock, but now it fails.")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
lockerObj.RUnlock()
|
||
|
|
lockerObj.RUnlock()
|
||
|
|
lockerObj.RUnlock()
|
||
|
|
|
||
|
|
if successful, _, _ := lockerObj.Lock(100); successful == false {
|
||
|
|
t.Errorf("It should be successful to get a write lock, but now it fails.")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if successful, _, _ := lockerObj.Lock(100); successful {
|
||
|
|
t.Errorf("It should be failed to get a write lock, but now it succeeds.")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if successful, _, _ := lockerObj.RLock(100); successful {
|
||
|
|
t.Errorf("It should be failed to get a read lock, but now it succeeds.")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
lockerObj.Unlock()
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRWNewLocker5(t *testing.T) {
|
||
|
|
count := 100
|
||
|
|
rwLockerObj := NewRWLocker()
|
||
|
|
ch := make(chan bool, 100)
|
||
|
|
|
||
|
|
for i := 0; i < count; i++ {
|
||
|
|
go func(num int, ch chan bool) {
|
||
|
|
if num%2 == 0 {
|
||
|
|
if successful, _, _ := rwLockerObj.Lock(100); successful {
|
||
|
|
fmt.Println("I get write lock.")
|
||
|
|
time.Sleep(2 * time.Millisecond)
|
||
|
|
rwLockerObj.Unlock()
|
||
|
|
} else {
|
||
|
|
fmt.Println("Write lock timeout")
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if successful, _, _ := rwLockerObj.RLock(100); successful {
|
||
|
|
fmt.Println("I get read lock.")
|
||
|
|
time.Sleep(2 * time.Millisecond)
|
||
|
|
rwLockerObj.RUnlock()
|
||
|
|
} else {
|
||
|
|
fmt.Println("Read lock timeout")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ch <- true
|
||
|
|
}(i, ch)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < count; i++ {
|
||
|
|
<-ch
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func rwLockerTest(lockerObj *RWLocker, succeedCount *int, count int, ch chan bool) {
|
||
|
|
if success, _, _ := lockerObj.Lock(10000); !success {
|
||
|
|
fmt.Printf("[%v]获取锁超时\n", time.Now())
|
||
|
|
return
|
||
|
|
}
|
||
|
|
defer lockerObj.Unlock()
|
||
|
|
|
||
|
|
for i := 0; i < count; i++ {
|
||
|
|
*succeedCount += 1
|
||
|
|
}
|
||
|
|
|
||
|
|
ch <- true
|
||
|
|
}
|