原子操作、互斥锁、读写锁

原子操作

package main

import (
    "fmt"
    "sync"
    "sync/atomic" //原子操作,比读写锁和互斥锁都要快,原子操作在用户态,其他锁在内核态
    "time"
)

var w sync.WaitGroup
var count int32

func main() {
    w.Add(1)
    start := time.Now().UnixNano()
    go func() {
        for i := 0; i < 1000000; i++ {
            atomic.AddInt32(&count, 1) //原子操作
        }
        w.Done()
    }()

    for i := 0; i < 1000000; i++ {
        atomic.AddInt32(&count, 1)
    }

    w.Wait()
    end := time.Now().UnixNano()
    fmt.Println((end - start) / 1000 / 1000)
    fmt.Println(count)
}


互斥锁

package main

import (
    "fmt"
    "sync"
    "time"
)

var lock sync.Mutex  //互斥锁
var w sync.WaitGroup //等待子线程退出
var count int

func main() {
    start := time.Now().UnixNano()
    w.Add(1) //相当于标记起一个子线程
    go func() {
        for i := 0; i < 1000000; i++ {
            lock.Lock()
            count++
            lock.Unlock()
        }
        w.Done() //相当于标记关闭一个子线程
    }()

    for i := 0; i < 1000000; i++ {
        lock.Lock()
        count++
        lock.Unlock()
    }

    w.Wait()
    end := time.Now().UnixNano()
    fmt.Println((end - start) / 1000 / 1000)
    fmt.Println(count)

}


读写锁

package main

import (
    "fmt"
    "sync"
    "time"
)

var rwLock sync.RWMutex //读写锁,读锁所有线程都可以同时用(除了写线程),但是同时写线程不能用写锁。用于读多写少。
var lock sync.Mutex
var w sync.WaitGroup
var count int

func main() {
    w.Add(1)
    start := time.Now().UnixNano()
    go func() {
        for i := 0; i < 1000; i++ {
            //rwLock.Lock()  //写锁
            lock.Lock() //互斥锁
            count++
            time.Sleep(5 * time.Millisecond)
            lock.Unlock()
            //rwLock.Unlock()
        }
        w.Done()
    }()

    for i := 0; i < 16; i++ {
        w.Add(1)
        go func() {
            for i := 0; i < 5000; i++ {
                //rwLock.RLock()  //读锁
                lock.Lock()
                time.Sleep(1 * time.Millisecond)
                lock.Unlock()
                //rwLock.RUnlock()
            }
            w.Done()
        }()
    }
    w.Wait()
    end := time.Now().UnixNano()
    fmt.Println((end - start) / 1000 / 1000)
    //fmt.Println(count)
}

 

posted @ 2018-03-25 16:39  shy车队破风手  阅读(795)  评论(0编辑  收藏  举报