多线程之Lock锁和读写锁ReadWriteLock
JDK1.5之后有提供了另一种加锁方式Lock锁。Lock
实现提供了比使用 synchronized
方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的Condition
对象。
锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如ReadWriteLock
的读取锁。
synchronized
方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。
而lock加锁之后必须我们搜索释放掉锁:
Lock l = ...; l.lock();try {// access the resource protected by this lock} finally {l.unlock();}
synchronized可以改写为如下:
package andy.thread.test;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** @author Zhang,Tianyou* @version 2014年11月8日 下午11:30:10*/public class ThreadLockTest {public static void main(String[] args) {A a = new A();new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}a.printfA(Thread.currentThread().getName()+ "hello, my is A");}}}).start();new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}a.printfA(Thread.currentThread().getName()+ "hello, my is B");}}}).start();}static class A {// 定义Lock锁Lock lock = new ReentrantLock();public void printfA(String name) {lock.lock();// 添加lock锁try {for (int i = 0; i < name.length(); i++) {System.out.print(name.charAt(i));}System.out.println();} finally {lock.unlock();// 无论加锁内容是否执行 都要释放锁}}}}
Lock 还提供了读写锁ReadWriteLock:
1 读取锁
可以由多个 reader 线程同时保持
2 写入锁
是独占的。
ReadWriteLock rwl = new ReentrantReadWriteLock();
一、读锁操作
rwl.readLock().lock();
rwl.readLock().unlock();
二、写锁操作
rwl.writeLock().lock();
rwl.writeLock().unlock();
实现读写所如下:
package andy.thread.test;import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;/*** @author Zhang,Tianyou* @version 2014年11月8日 下午11:44:01*/public class ReadWriteLockTest {public static void main(String[] args) {final A a = new A();for (int i = 0; i < 3; i++) {new Thread() {public void run() {while (true) {a.get();}}}.start();new Thread() {public void run() {while (true) {a.put(new Random().nextInt(10000));}}}.start();}}}class A {private Object data = null;// 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。ReadWriteLock rwl = new ReentrantReadWriteLock();public void get() {rwl.readLock().lock();try {System.out.println(Thread.currentThread().getName()+ " be ready to read data!");Thread.sleep((long) (Math.random() * 1000));System.out.println(Thread.currentThread().getName()+ "have read data :" + data);} catch (InterruptedException e) {e.printStackTrace();} finally {rwl.readLock().unlock();}}public void put(Object data) {rwl.writeLock().lock();try {System.out.println(Thread.currentThread().getName()+ " be ready to write data!");Thread.sleep((long) (Math.random() * 1000));this.data = data;System.out.println(Thread.currentThread().getName()+ " have write data: " + data);} catch (InterruptedException e) {e.printStackTrace();} finally {rwl.writeLock().unlock();}}
}
运行效果如下:
Thread-0 be ready to read data!
Thread-4 be ready to read data!
Thread-2 be ready to read data!
Thread-0have read data :null
Thread-2have read data :null
Thread-4have read data :null
Thread-1 be ready to write data!
Thread-1 have write data: 5730
Thread-1 be ready to write data!
Thread-1 have write data: 7997
Thread-1 be ready to write data!
Thread-1 have write data: 2306
Thread-1 be ready to write data!
Thread-1 have write data: 8944
Thread-1 be ready to write data!
Thread-1 have write data: 8039
Thread-1 be ready to write data!
Thread-1 have write data: 6844
Thread-1 be ready to write data!
Thread-1 have write data: 2969
Thread-1 be ready to write data!
多线程之Lock锁和读写锁ReadWriteLock相关推荐
- C# lock 语法糖实现原理--《.NET Core 底层入门》之自旋锁,互斥锁,混合锁,读写锁...
在多线程环境中,多个线程可能会同时访问同一个资源,为了避免访问发生冲突,可以根据访问的复杂程度采取不同的措施 原子操作适用于简单的单个操作,无锁算法适用于相对简单的一连串操作,而线程锁适用于复杂的一连 ...
- 锁Lock,主要是重入锁和读写锁
2019独角兽企业重金招聘Python工程师标准>>> 在java多线程中,我们可以使用synchronized关键字来实现线程之间的同步互斥工作.还有一个更优秀的机制去完成这个&q ...
- java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)
前言 本文对Java的一些锁的概念和实现做个整理,涉及:公平锁和非公平锁.可重入锁(又名递归锁).自旋锁.独占锁(写)/共享锁(读)/互斥锁.读写锁 公平锁和非公平锁 概念 公平锁是指多个线程按照申请 ...
- golang:1.并发编程之互斥锁、读写锁详解
本文转载自junjie,而后稍作修改. 一.互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段.它由标准库代码包sync中的Mutex结构体类型代表.sync.Mutex类型(确切地说,是 ...
- PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
文件锁全名叫 advisory file lock, 书中有提及. 这类锁比较常见,例如 mysql, php-fpm 启动之后都会有一个pid文件记录了进程id,这个文件就是文件锁. 这个锁可以防止 ...
- java线程:互斥锁与读写锁
2019独角兽企业重金招聘Python工程师标准>>> 两种互斥锁机制: 1.synchronized 2.ReentrantLock ReentrantLock是jdk5的新特性, ...
- 谈谈java并发锁(重入锁、读写锁、公平锁)
目录 重入锁 简单重入锁 重入锁的等待通知(Condition) 多Condition 公平锁和非公平锁 读写锁ReentrantReadWriteLock 锁优化总结: 重入锁和读写锁,他们具有比s ...
- 同步方法中的锁对象_互斥锁与读写锁:如何使用锁完成Go程同步?
图转自https://colobu.com/2018/12/18/dive-into-sync-mutex/ 这张图容易让人产生误解,容易让人误以为goroutine1获取的锁,只有goroutine ...
- Java多线程学习十六:读写锁 ReadWriteLock 获取锁有哪些规则
读写锁 ReadWriteLock 获取锁有哪些规则呢? 在没有读写锁之前,我们假设使用普通的 ReentrantLock,那么虽然我们保证了线程安全,但是也浪费了一定的资源,因为如果多个读操作同时进 ...
- java读写锁死锁例子_Java并发关于重入锁与读写锁的详解
这篇文章主要介绍了Java并发编程之重入锁与读写锁,文中相关实例代码详细,测试可用,具有一定参考价值,需要的朋友可以了解下. 重入锁 重入锁,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对 ...
最新文章
- 基于Protobuf共享字段的分包和透传零拷贝技术,你了解吗?
- 【Usaco2014Open银组】照相(pairphoto)
- 2014年度辛星解读css第四节
- 一个最简单的UDP通信
- Error occurred while trying to proxy request
- Django连接现有mysql数据库
- 优达学城深度学习之一——Anaconda
- ST算法 Sliding Window algorithm template
- STP的根端口与指定端口
- 单片机C语言步进电机实训报告,单片机实验报告步进电机.doc
- 微信native支付
- 99,36岁老码农现身说法
- springboot发送邮件
- SQL中OVER(PARTITION BY)详解
- 几种基本放大电路详解
- Linux ubuntu下载vim
- python io多路复用
- doc转docx文件会乱吗_Word中doc和docx,到底有什么区别
- MongoDB 空间定位(点) 与 距离检索
- arcmap中图斑面积代表_【干货】ArcGIS四种计算图斑面积的方法
热门文章
- 易筋SpringBoot 2.1 | 第十五篇:SpringBoot连接池Druid
- sds数据结构,Simple Dynamic String,简单动态字符串
- 轻量级神经网络ShuffleNet
- 计算机采用二进制码的优点
- Oracle 10g 数据库连接出现The Network Adapter could not establish the connection解决办法
- 爱情指数测试脸型软件,心理测试:你和谁的脸型最像?测出你的幸运指数是多少!...
- LRU算法的一种实现方法
- 【ECG实践篇(1)】MIT-BIH数据库数据解析的方法以及使用rdann获取人工标注注释的方法
- 【PRML 学习笔记】第二章 - 概率分布 (Probability Distributions)
- 【Codeforces Round #516_div2_E】【二分交互题】Dwarves, Hats and Extrasensory Abilities