读-写锁 ReadWriteLock & 线程八锁
读-写锁 ReadWriteLock:
①ReadWriteLock 维护了一对相关的锁,一个用于只读操作, 另一个用于写入操作。
只要没有 writer,读取锁可以由 多个 reader 线程同时保持。写入锁是独占的。。
②ReadWriteLock 读取操作通常不会改变共享资源,但执行 写入操作时,必须独占方式来获取锁。
对于读取操作占多数的数据结构。 ReadWriteLock 能提供比独占锁更高 的并发性。
而对于只读的数据结构,其中包含的不变性可以完全不需要考虑加锁操作
TestReadWriteLock
package com.aff.juc; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class TestReadWriteLock {
public static void main(String[] args) {
ReadWriteLockDemo rw = new ReadWriteLockDemo();
new Thread(new Runnable() {
@Override
public void run() {
rw.set((int) Math.random() * 101);// [0-100]随机整数, 100+1 为[1-00]
}
}, "一个线程写:").start(); for (int i = 0; i <= 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
rw.get();
}
}).start();
}
}
} class ReadWriteLockDemo { private int number = 0;
private ReadWriteLock lock = new ReentrantReadWriteLock(); // 读取
public void get() {
lock.readLock().lock();// 上锁
try {
System.out.println(Thread.currentThread().getName() + " : " + number);
} finally {
lock.readLock().unlock();// 释放锁
}
} // 写
public void set(int number) { lock.writeLock().lock();// 上锁
try {
System.out.println(Thread.currentThread().getName());
this.number = number;
} finally {
lock.writeLock().unlock();// 释放锁
}
}
}
线程八锁:
① 一个对象里面如果有多个synchronized方法,某一个时刻内,
只要一个线程去调用 其中的一个synchronized方法了,
其它的线程都只能等待,换句话说,某一个时刻 内,只能有唯一一个线程去访问这些synchronized方法
② 锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的 synchronized方法
③ 加个普通方法后发现和同步锁无关
④ 换成两个对象后,不是同一把锁了,情况立刻变化。
⑤ 都换成静态同步方法后,情况又变化
⑥ 所有的非静态同步方法用的都是同一把锁——实例对象本身,
也就是说如果一个实 例对象的非静态同步方法获取锁后,
该实 例对象的其他非静态同步方法必须等待获 取锁的方法释放锁后才能获取锁,
可是别的实例对象的非静态同步方法因为跟该实 例对象的非静态同步方法用的是不同的锁,
所以毋须等待该实例对象已获取锁的非 静态同步方法释放锁就可以获取他们自己的锁。
⑦ 所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对 象,
所以静态同步方法与非静态同步方法之间是不会有竞态条件的。但是一旦一个 静态同步方法获取锁后,
其他静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法
之间还是不同的实例对象的静态同 步方法之间,只要它们同一个类的实例对象!
关键点:①非静态方法的默认锁为 this,静态方法的默认锁为对应的 Class 实例
②某一时刻内,只能有一个线程持有锁,无论几个方法。
读-写锁 ReadWriteLock & 线程八锁的更多相关文章
- (三)juc高级特性——虚假唤醒 / Condition / 按序交替 / ReadWriteLock / 线程八锁
8. 生产者消费者案例-虚假唤醒 参考下面生产者消费者案例: /* * 生产者和消费者案例 */ public class TestProductorAndConsumer { public stat ...
- 线程中的读写锁ReadWriteLock
Lock锁还有两个非常强大的类 ReadWriteLock接口实现类ReentrantReadWriteLock(非常重要的锁) 想实现 读取的时候允许多线程并发访问,写入的时候不允许. 这种效果.. ...
- 显式锁(三)读写锁ReadWriteLock
前言: 上一篇文章,已经很详细地介绍了 显式锁Lock 以及 其常用的实现方式- - ReetrantLock(重入锁),本文将介绍另一种显式锁 - - 读写锁ReadWriteLock. ...
- 【漫画】互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock
ReentrantLock完美实现了互斥,完美解决了并发问题.但是却意外发现它对于读多写少的场景效率实在不行.此时ReentrantReadWriteLock来救场了!一种适用于读多写少场景的锁,可以 ...
- C# 多线程编程之锁的使用【互斥锁(lock)和读写锁(ReadWriteLock)】
多线程编程之锁的使用[互斥锁(lock)和读写锁(ReadWriteLock)] http://blog.csdn.net/sqqyq/article/details/18651335 多线程程序写日 ...
- 【漫画】读写锁ReadWriteLock还是不够快?再试试StampedLock!
本文来源于公众号[胖滚猪学编程] 转载请注明出处! 在互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock一文中,我们对比了互斥锁ReentrantLock和读写锁ReadWr ...
- Java 读写锁 ReadWriteLock 原理与应用场景详解
Java并发编程提供了读写锁,主要用于读多写少的场景,今天我就重点来讲解读写锁的底层实现原理@mikechen 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Loc ...
- 线程同步——用户模式下线程同步——Slim读写锁实现线程同步
//Slim读/写锁实现线程同步 SRWlock 的目的和关键段相同:对同一资源进行保护,不让其它线程访问. 但是,与关键段不同的是,SRWlock允许我们区分哪些想要读取资源的线程(读取者线程) 和 ...
- Linux:使用读写锁使线程同步
基础与控制原语 读写锁 与互斥量类似,但读写锁允许更高的并行性.其特性为:写独占,读共享. 读写锁状态: 一把读写锁具备三种状态: 1. 读模式下加锁状态 (读锁) 2. 写模式下加锁 ...
随机推荐
- 题解 CF588A 【Duff and Meat】
题意 有一个人,想吃 $n$ 天肉,第 $i$ 天需要吃 $a[i]$ 块肉,第 $i$ 天超市肉价为每块 $b[i]$ 元,买来的肉可以留到后面吃,求这个人在每天都吃到肉的情况下花费的最小值. 题目 ...
- python2执行程序报错:NameError: name 'y' is not defined
然后运行一直报错 这个错误,是由于版本不同造成的语法错误,在python3中,输入可以使用input,但如果你的版本是python2,那么此时input就得改成raw_input,否则你输入数据会被当 ...
- 使用Proteus模拟操作HDG12864F-1液晶屏
在Proteus中模拟了89C52操作HDG12864F-1液晶屏,原理图如下: 一.HDG12864F-1官网信息 该液晶屏是Hantronix的产品,官网上搜索出这个型号是系列型号中的一种,各种型 ...
- 测试开发专题:spring-boot统一异常捕获
java异常介绍 异常时相对于return的一种退出机制,可以由系统触发,也可由程序通过throw语句触发,异常可以通过try/catch语句进行捕获并处理,如果没有捕获,则会导致程序退出并输出异常栈 ...
- 自动化运维工具Ansible之LNMP实践环境部署
Ansible-实战指南-LNMP环境部署,并使用zabbix监控 主机规划 系统初始化:必要的系统初始化 基础组件包括:zabbix监控,mariadb(用于存放zabbix监控信息) 业务组件包括 ...
- 使用 React hooks 转化 class 的一些思考
Hooks 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性. 使用 React hooks 转化 class 的一些思考 ...
- 对文本的内容进行排序(io流、集合操作)
package com.itheima.demo01.BufferedStream; import java.io.*; import java.util.HashMap; /* 练习: 对文本的内容 ...
- 非系统盘根目录出现msdia80.dll文件,能否删除?
出现此问题的原因:计算机上安装了 Microsoft Visual C++ 2005 可再发行组件时,Msdia80.dll文件被错误安装在其他驱动器的根文件夹中. 它的正确路径应该是"C: ...
- python常识系列08-->logging模块基础入门
前言 努力从今天开始,成功从"零"开始. 一.logging模块是什么? 是Python内置的标准模块,主要用于输出运行日志 二.日志是什么? 日志是代码的必要组成部分 记录日志能 ...
- Spring初学笔记(二):Bean的注入
关于Bean的注入 在上一篇中,已经说到虽然注入确实可以降低类与类之间的耦合,但并没有解决调用者必须知道类的创建方法的问题,也可以说是没有实现调用者与类实现的解耦,我们也提到,为了实现两者的解耦,可以 ...