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

原子操作

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)
}

原文地址:https://www.cnblogs.com/domestique/p/8645362.html

时间: 2024-08-02 16:06:11

原子操作、互斥锁、读写锁的相关文章

Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁

synchronized 是互斥锁: lock 更广泛,包含了读写锁 读写锁特点: 1)多个读者可以同时进行读2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者) 互斥锁特点: 一次只能一个线程拥有互斥锁,其他线程只有等待 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问. 而现在, Lock提供了比synchronize

Go同步等待组/互斥锁/读写锁

1. 临界资源 package main import ( "fmt" "time" ) func main() { /* 临界资源: */ a := 1 go func() { a = 2 fmt.Println("goroutine中..",a) }() a = 3 time.Sleep(1) fmt.Println("main goroutine...",a) //2 } 2. 同步等待组 package main im

QThread中的互斥、读写锁、信号量、条件变量

该文出自:http://www.civilnet.cn/bbs/browse.php?topicno=78431 在gemfield的<从pthread到QThread>一文中我们了解了线程的基本使用,但是有一大部分的内容当时说要放到这片文章里讨论,那就是线程的同步问题.关于这个问题,gemfield在<从进 程到线程>中有一个比喻,有必要重新放在下面温习下: ******************************* 最后用一个比喻来总结下: 1.一个进程就好比一个房子里有一

自旋锁&amp;读/写锁

自旋锁 自旋锁(spin lock)是用来在多处理器环境中工作的一种特殊的锁.如果内核控制路径发现自旋锁"开着",就获取锁并继续自己的执行.相反,如果内核控制路径发现由运行在另一个CPU上的内核控制路径"锁着",就在一直循环等待,反复执行一条紧凑的循环指令,直到锁被释放. 一般来说,由自旋锁所保护的每个临界区都是禁止内核抢占的.在单处理器系统上,这种锁本身并不起锁的作用,自旋锁原语仅仅是禁止或启用内核抢占.请注意,在自旋锁忙等期间,内核抢占还是有效的,因此,等待自旋

锁,同步,可重入锁,读写锁(转)

1.synchronized 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性(atomicity)和 可见性(visibility). 1.1 原子性 原子性意味着个时刻,只有一个线程能够执行一段代码,这段代码通过一个monitor object保护.从而防止多个线程在更新共享状态时相互冲突. 1.2 可见性 可见性则更为微妙,它要对付内存缓存和编译器优化的各种反常行为.它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 . 作用:

linux 内核的另一个自旋锁 - 读写锁

除spinlock外,linux 内核还有一个自旋锁,名为arch_rwlock_t.它的头文件是qrwlock.h,包含在spinlock.h,头文件中对它全称为"Queue read/write lock".这个锁只使用了两个成员变量就实现了读写锁.一个spinlock,以及一个整形锁变量.而spinlock就是这个Queue. 锁的原理是,当没有写意愿或写锁使用时,任意读锁可以并发.当有写意愿或写锁使用时,一切的读锁和写锁都必须进行排队. arch_rwlock_t的锁变量虽然只

Linux系统编程——线程同步与互斥:读写锁

当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住.但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是由于互斥锁的排它性,所有其它线程都无法获取锁,也就无法读访问共享资源了,但是实际上多个线程同时读访问共享资源并不会导致问题. 在对数据的读写操作中,更多的是读操作,写操作较少,例如对数据库数据的读写应用.为了满足当前能够允许多个读出,但只允许一个写入的需求,线程提供了读写锁来实现.... www.worlduc.com/

可重入锁 公平锁 读写锁

1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这种情况出现在多任务系统当中,在任务执行期间捕捉到信号并对其进行处理时,进程正在执行的指令序列就被信号处理程序临时中断.如果从信号处理程序返回,则继续执行进程断点处的正常指令序列,从重新恢复到断点重新执行的过程中,函数所依赖的环境没有发生改变,就说这个函数是可重入的,反之就是不可重入的.众所周知,在进

06 锁:可重入锁 公平锁 读写锁

1.可重入锁 如果锁具备可重入性,则称作为可重入锁. 像synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制: 基于线程的分配,而不是基于方法调用的分配. 举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2, 此时线程不必重新去申请锁,而是可以直接执行方法method2. class MyClass { public synch

通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底层实现浅尝辄止,但是在需要时能够知道去查什么. 首先要打消一种想法,就是一个锁只能属于一种分类.其实并不是这样,比如一个锁可以同时是悲观锁.可重入锁.公平锁.可中断锁等等,就像一个人可以是男人.医生.健身爱好者.游戏玩家,这并不矛盾.OK,国际惯例,上干货. 〇.synchronized与Lock