读写锁

current包下ReentrantReadWriteLock的使用

与世无争的帅哥 提交于 2020-04-12 14:02:47
ReentrantReadWriteLock中可以生产读锁和写锁。 读锁和读锁不互斥,写锁和任何读锁或者写锁都互斥。 demo:读锁和读锁不互斥 public static void main(String[] args) { ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); final ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock(); final ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock(); for (int i = 0; i < 5; i++) { new Thread(new Runnable() { public void run() { try { readLock.lock(); System.out.println(Thread.currentThread().getName() + " 开始读取数据"); TimeUnit.SECONDS.sleep(5); System.out.println(Thread.currentThread()

java之AQS和显式锁

China☆狼群 提交于 2020-03-23 09:46:55
  本次内容主要介绍AQS、AQS的设计及使用、 ReentrantLock、 ReentrantReadWriteLock以及手写一个可重入独占锁 1、什么是AQS ?    A QS,队列同步器AbstractQueuedSynchronizer的简写,JDK1.5引入的, 是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。AQS的作者Doug Lea大师期望它能够成为实现大部分同步需求的基础。 2、AQS的设计及其作用    AbstractQueuedSynchronizer是一个抽象类,先看一下其类图。   AQS中里有一个volatile修饰int型的state来代表同步状态,使用同步器提供的3个方法(getState()、setState(int newState)和compareAndSetState(int expect,int update))来改变状态,因为它们能够保证状态的改变是安全的。   AQS使用的是模板方法模式,主要使用方式是继承,且通常将子类推荐定义为静态内部类,子类通过继承AQS并实现它的抽象方法来管理同步状态。AQS自身没有实现任何同步接口,它仅仅是定义了若干同步状态获取和释放的方法来供自定义同步组件使用,同步器既可以支持独占式地获取同步状态

JAVA线程锁-读写锁

我只是一个虾纸丫 提交于 2020-03-20 00:11:07
  JAVA线程锁,除Lock的传统锁,又有两种特殊锁,叫读写锁ReadWriteLock   其中多个读锁不互斥,读锁和写锁互斥,写锁和写锁互斥 例子: /** * java线程锁分为读写锁 ReadWriteLock 其中多个读锁不互斥,读锁和写锁互斥,写锁和写锁互斥 * * @author * * * */ public class ReadWriteLockTest { public static void main(String[] args) { final Operation operation = new Operation(); for (int i = 1; i <= 3; i++) { new Thread(new Runnable() { @Override public void run() { operation.getData(); } }).start(); new Thread(new Runnable() { @Override public void run() { operation.putData(new Random().nextInt(1000)); } }).start(); } } } class Operation{ private ReadWriteLock rwl = new ReentrantReadWriteLock();

读写锁分离的循环队列

空扰寡人 提交于 2020-03-14 05:21:05
在很多需要高性能的场合下,锁的设计一直是一个比较关键的问题。无锁队列、读写锁分离的队列在业界以及学术界都已经有很成熟的研究。在网上也有很多资料, 但其实有很多实现都是错误的 。最近在工作中帮忙追查一个线上问题时,就发现实现一个正确的版本是比较困难的事情。 背景:实现一个循环队列,队列长度已预先分配。支持不同线程的多写多读。 原本的实现是对读和写分别使用了两个不同的锁来提升性能,但是在最早实现的时候 并没有发现到 线程间数据的同步修改会造成小概率读取脏数据 导致线上服务有问题 。 1 size_t Queue::pop(int &value) 2 { 3 AutoLock lock(_poplock); 4 if (!empty()) { 5 value = _queue[_read]; 6 ++ _read; 7 if (_read == _maxsize) { 8 _read = 0; 9 } 10 return 1;11 }12 return 0;13 }14 15 size_t Queue::push(int value)16 {17 AutoLock lock(_pushlock);18 if (!full()) {19 _queue[_write] = value;20 ++ _write;21 if (_write == _maxsize) {22 _write = 0

多线程-读写锁

懵懂的女人 提交于 2020-03-06 09:00:35
1. 读写锁 ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。 Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性 假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。 对于lock的读写锁,可以通过new ReentrantReadWriteLock()获取到一个读写锁。所谓读写锁,便是多线程之间读不互斥,读写互斥。读写锁是一种自旋锁,如果当前没有读者,也没有写者,那么写者可以立刻获得锁,否则它必须自旋在那里,直到没有任何写者或读者。如果当前没有写者,那么读者可以立即获得该读写锁,否则读者必须自旋在那里,直到写者释放该锁 简单来说就是 独占锁(写锁):一次只能被一个线程占有 共享锁(读锁):该锁可以被多个线程占有! 先看一下没有锁的情况 package demo.ReadWriteLock; ​ import java.util.HashMap; import java.util.Map; ​

单例模式、读写锁

喜夏-厌秋 提交于 2020-03-02 10:18:06
单例模式 是设计模式中的一种,是大佬们针对典型场景设计的解决方案。 典型场景:一个对象/一个资源 只能被初始化加载一次 。 例如:你在打游戏的时候,游戏有很多图片资源。希望一个图片只加载一次。 实现方式 : 饿汉/懒汉 饿汉:所有资源在程序初始化阶段 一次性 完成初始化(资源在初始化的时候一次性全部加载,后续只需要使用就可以) template<class T> class single { static T _data;//所以实例化的对象共用同一份资源 T* get_instance() { return &_data; } } 资源初始化的时候会慢一点,但是运行起来以后,会很流畅。 懒汉:资源在 使用的时候 进行初始化(用到的时候再去加载,当然也要保证只加载一次) template <typename T> class Singleton { static T* inst; public: static T* GetInstance() { if (inst == NULL) { inst = new T(); } return inst; } } 在使用的时候加载一次资源,会涉及到线程安全问题。(volatile、static、mutex、二次判断) 使用static保证多个对象使用 同一份 空间资源。(保证资源只被加载一次,实现单例模式) 加锁保护资源申请过程

线程之线程同步

风流意气都作罢 提交于 2020-03-01 12:51:01
本文来自个人博客: https://dunkwan.cn 文章目录 线程同步 互斥量 函数`pthread_mutex_timedlock` 读写锁 带有超时的读写锁 条件变量 自旋锁 屏障 线程同步 互斥量 互斥量从本质上来说是一把锁,在访问共享资源前对互斥量进行设置,在访问完成后释放互斥量。互斥量使用 pthread_mutex_t 数据类型表示的。在使用互斥量以前,必须首先对它进行初始化,可以把它设置为常量 PTHREAD_MUTEX_INITIALIZER (只适用于静态分配的互斥量),也可以通过调用 pthread_mutex_init 函数进行初始化。如果动态分配互斥量(例如通过调用 malloc 函数),在释放内存前需要调用 pthread_mutex_detroy 。 # include <pthread.h> int pthread_mutex_init ( pthread_mutex_t * restrict mutex , const pthread_mutexattr_t * restrict attr ) ; int pthread_mutex_destroy ( pthread_mutex_t * mutex ) ; 两个函数的返回值:若成功,返回 0 ;否则,返回错误编号。 要用默认的属性初始化互斥量,只需把 attr 设为 NULL 。

多线程读写锁

不打扰是莪最后的温柔 提交于 2020-02-27 15:03:12
package com.thread.ch6; public class ReadWriteLock { //正在读的用户数 private int readingReaders = 0; //等待读的用户数量 private int waitingReaders = 0; //正在写的用户数量 private int writingWriters = 0; //等待写的用户数量 private int waitingWriters = 0; private boolean preferWriter = true; public ReadWriteLock() { this(true); } public ReadWriteLock(boolean preferWriter) { this.preferWriter = preferWriter; } public synchronized void readLock() { //读的人加1 this.waitingReaders++; try { //当写的人数大于0 或者偏向写为true 且等待写的人数大于0 则当前读等待 while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) { this.wait(); } this.readingReaders+

c 读写锁 -demo

北城以北 提交于 2020-02-27 01:45:25
#include <pthread.h> #include <stdio.h> #include <unistd.h> void readFunc(); void writeFunc(); int data = 0; pthread_rwlock_t rwlock; int main() { pthread_rwlock_init(&rwlock, NULL); pthread_t readThread; pthread_t writeThread; pthread_t readThread1; pthread_create(&readThread, NULL, readFunc, NULL); pthread_create(&writeThread, NULL, writeFunc, NULL); pthread_create(&readThread1, NULL, readFunc, NULL); pthread_join(readThread, NULL); pthread_join(writeThread, NULL); pthread_join(readThread1, NULL); pthread_rwlock_destroy(&rwlock); return 0; } void readFunc() { while (1) { pthread_rwlock

读写锁之ReadWriteLock

江枫思渺然 提交于 2020-02-24 08:43:18
你可能有这样一个疑问,Java SDK 并发包里为什么还有很多其他的工具类呢?原因很简单: 分场景优化性能,提升易用性 。 接下来我们聊聊,针对读多写少这种并发场景,Java SDK 并发包提供了读写锁——ReadWriteLock 读写锁,并不是 Java 语言特有的,而是一个广为使用的通用技术,所有的读写锁都遵守以下三条,尤其注意第三条,之后我们讲跟其他锁的对比会用到。 基本原则: 1. 允许多个线程同时读共享变量; 2.只允许一个线程写共享变量; 3. 如果一个写线程正在执行写操作,此时禁止读线程读共享变量(读写锁不能同时存在) 互斥锁: 互斥锁 互斥锁 升降级 ReadWriteLock 读操作允许多个线程同时读共享变量 写操作是互斥的,当一个 线程在写共享变量的时候,是不允许其他线程执行写操作和读操作。 不允许升级,允许降级。 读锁不支持条件变量 newCondition() 读写锁在读多写少场景下性能优于互斥锁的关键 总结: 读写锁类似于 ReentrantLock,也支持公平模式和非公平模式。读锁和写锁都实现了 java.util.concurrent.locks.Lock 接口,所以除了支持 lock() 方法外,tryLock()、 lockInterruptibly() 等方法也都是支持的。但是有一点需要注意,那就是只有写锁支持条件变量, 读锁是不支持条件变量的