自旋锁

Spin lock 与mutex 的区别--2011.01.06

ぃ、小莉子 提交于 2020-03-28 05:12:28
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享的临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。 Pthreads提供了多种锁机制: (1) Mutex(互斥量):pthread_mutex_*** (2) Spin lock(自旋锁):pthread_spin_*** (3) Condition Variable(条件变量):pthread_con_*** (4) Read/Write lock(读写锁):pthread_rwlock_*** Pthreads提供的Mutex锁操作相关的API主要有: pthread_mutex_lock (pthread_mutex_t *mutex); pthread_mutex_trylock (pthread_mutex_t *mutex); pthread_mutex_unlock (pthread_mutex_t *mutex); Pthreads提供的与Spin Lock锁操作相关的API主要有: pthread_spin_lock (pthread_spinlock_t

Spin lock 与mutex 的区别

可紊 提交于 2020-03-28 05:09:59
转自http://blog.csdn.net/kyokowl/article/details/6294341 POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享的临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。 Pthreads提供了多种锁机制: (1) Mutex(互斥量):pthread_mutex_*** (2) Spin lock(自旋锁):pthread_spin_*** (3) Condition Variable(条件变量):pthread_con_*** (4) Read/Write lock(读写锁):pthread_rwlock_*** Pthreads提供的Mutex锁操作相关的API主要有: pthread_mutex_lock (pthread_mutex_t *mutex); pthread_mutex_trylock (pthread_mutex_t *mutex); pthread_mutex_unlock (pthread_mutex_t *mutex); Pthreads提供的与Spin

Java关键字-synchronized

时光毁灭记忆、已成空白 提交于 2020-03-28 03:08:43
synchronized 关键字的三种使用方式   修饰实例方法,作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁。   修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 。也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态资源,不管new了多少个对象,只有一份,所以对该类的所有对象都加了锁)。所以如果一个线程A调用一个实例对象的非静态 synchronized 方法,而线程B需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁。   修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。 和 synchronized 方法一样,synchronized(this)代码块也是锁定当前对象的。synchronized 关键字加到 static 静态方法和 synchronized(class)代码块上都是是给 Class 类上锁。需要注意的是:尽量不要使用 synchronized(String a) 因为JVM中,字符串常量池具有缓冲功能! synchronized

记一次 “排它锁" 和 "自旋锁" 的简单实现

谁都会走 提交于 2020-03-27 20:49:35
3 月,跳不动了?>>> 记一次 排它锁 和 自旋锁 的简单实现 定义一个lock接口 public interface PutMessageLock { void lock(); void unlock(); } 排它锁实现 使用java自带的 ReentrantLock 即可 public class PutMessageReentrantLock implements PutMessageLock { private ReentrantLock putMessageNormalLock = new ReentrantLock(); // NonfairSync @Override public void lock() { putMessageNormalLock.lock(); } @Override public void unlock() { putMessageNormalLock.unlock(); } } 自旋锁实现 使用 cas + 循环 来实现 public class PutMessageSpinLock implements PutMessageLock { //true: Can lock, false : in lock. private AtomicBoolean putMessageSpinLock = new AtomicBoolean(true)

自旋锁、排队自旋锁、MCS锁、CLH锁

十年热恋 提交于 2020-03-26 11:30:14
3 月,跳不动了?>>> 自旋锁(Spin lock) 自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。 自旋锁适用于锁保护的临界区很小的情况,临界区很小的话,锁占用的时间就很短。 简单的实现 import java.util.concurrent.atomic.AtomicReference; public class SpinLock { private AtomicReference<Thread> owner = new AtomicReference<Thread>(); public void lock() { Thread currentThread = Thread.currentThread(); // 如果锁未被占用,则设置当前线程为锁的拥有者 while (owner.compareAndSet(null, currentThread)) { } } public void unlock() { Thread currentThread = Thread.currentThread(); // 只有锁的拥有者才能释放锁 owner.compareAndSet(currentThread, null); } } SimpleSpinLock里有一个owner属性持有锁当前拥有者的线程的引用

java中锁的概念

北慕城南 提交于 2020-03-25 16:40:28
可重入锁(递归锁) 本文里面讲的是广义上的可重入锁,而不是单指 JAVA 下的 ReentrantLock。可重入锁,也叫做递归锁,指的是 同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响 。在 JAVA 环境下 ReentrantLock 和 synchronized 都是 可重入锁。当然有可重入锁就有不可重入锁,不可重入锁就是 同一线程 外层函数获得锁之后 ,只能当前函数使用 package com.yjc.juc; import java.util.concurrent.locks.ReentrantLock; class ZiYuan { ReentrantLock reentrantLock = new ReentrantLock(); public void method1() { reentrantLock.lock(); try { System.out.println("进入方法1"); System.out.println("准备调用方法2"); method2(); } catch (Exception e) { e.printStackTrace(); } finally { reentrantLock.unlock(); } } public void method2() { reentrantLock.lock(); try

一个自旋锁的栗子

大兔子大兔子 提交于 2020-03-21 17:27:13
  一直以来不是怎么清楚自旋锁,最近有点时间,好好的学习了一下;   所谓的自旋锁在我的理解就是多个线程在尝试获取锁的时候,其中一个线程获取锁之后,其他的线程都处在一直尝试获取锁的状态,不会阻塞!!!那么什么叫做一直尝试获取锁呢?就是一个循环,比较经典的是AtomicInteger中的一个updateAndGet方法,下图所示(当然也可以直接看unsafe类中的getAndAddInt等类似方法);   我们可以看出在while循环中使用CAS去尝试更新一个变量,如果更新失败,就会一直在这个循环中一直在尝试;成功的话,就可以到最后的return语句;   由此我们可以大概知道如果自旋的线程过多,那么CPU的资源就会被大量消耗!!!   顺便提一个东西叫做原子引用,官方提供了AtomicInteger,AtomicBoolean等原子类,那么如果我们自己定义的类也需要有原子性怎么办呢?所以官方提供了一个AtomicReference类,可以将我们自己定义的类封装一下,就成了我们自己的原子类,例如AtomicReference<Student> atomicReference = new AtomicReference<>();,然后我们对Student的实例进行CAS各种CAS操作;   栗子: package TestMain; import lombok.extern.slf4j

多线程 -- CAS自旋锁、Atomic类

廉价感情. 提交于 2020-03-18 17:01:03
1、CAS(compare and swap) CAS 概念: CAS是一种系统原语,能够原子地完成比较和交换两个动作(所谓原语属于操作系统用语范畴。原语由若干条指令组成的,用于完成一定功能的一个过程。primitive or atomic action 是由若干个机器指令构成的完成某种特定功能的一段程序,具有不可分割性·即原语的执行必须是连续的,在执行过程中不允许被中断)。CAS是Compare And Set的缩写。CAS有3个操作数,内存值V,旧的预期值E,要修改的新值N。当且仅当预期值E和内存值V相同时,将内存值V修改为B,否则什么都不做。 CAS 执行流程图: 2、自旋锁 (spinlock) 前言: 在介绍自旋锁之前,需要提到关键字 Volatile,它可以保证 JMM 模型所规定的可见性+有序性,但是它却不能保证原子性,即如果用它是不能保证对修饰变量操作的原子性的。因此不能用它来作为锁,但是它配合上 CAS 就可以构造出一种“无锁策略”的乐观自旋锁,保证了操作的原子性,而且在适合其应用的场景下效率是比较高的,因为它的优点就是可以避免线程的上下文切换所带来的系统开销。 概念: 是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。 自旋锁缺点: 1)如果某个线程持有锁的时间过长

乐观锁与悲观锁、自旋锁

做~自己de王妃 提交于 2020-03-11 03:33:08
乐观锁 乐观锁是一种乐观的思想,即认为读多写少,遇到并发的可能性低, 每次拿数据时都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据 ,可以使用版本号机制和 CAS 算法实现。 Java 中的乐观锁基本都是通过 CAS 操作实现的, CAS 是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。 悲观锁 悲观锁就是悲观的思想,即认为写多,遇到并发的可能性高,每次拿数据时,都会认为别人会修改数据,所以在每次读数据的时候都会上锁,这样当别人想读写这个数据时就会阻塞,直到拿到锁。 (共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程) 。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 Java 中的悲观锁就是 Synchronized,AQS 框架下的锁则是先尝试 CAS 乐观锁去获取锁,获取不到,才会转换为悲观锁,如 ReentrantLock。 乐观锁的缺点 ABA 问题 CAS 会导致 “ABA 问题”。CAS 算法实现的一个重要前提是需要取出内存中某时刻的数据,而在下一时刻比较并替换,那么在这个时间差会导致数据的变化。 比如说一个线程 one 从内存位置 V 中取出 A,这时候另一个线程 two 也从内存中取出 A,并且 two

java自旋锁的代码实现

大兔子大兔子 提交于 2020-03-07 20:49:32
自旋锁:spinlock 是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环好用CPU 代码: import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; public class SpinLockDemo { //原子引用线程 AtomicReference<Thread> atomicReference = new AtomicReference<>(); public void myLock() { Thread thread = Thread.currentThread(); System.out.println(Thread.currentThread().getName() + "\t come in "); while (!atomicReference.compareAndSet(null, thread)) { } } public void myUnlock() { Thread thread = Thread.currentThread(); atomicReference.compareAndSet(thread, null); System.out.println(Thread