hadoop08---读写锁
- ReentrantLock
- 直接使用lock接口的话,我们需要实现很多方法,不太方便,ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法,ReentrantLock,意思是“可重入锁”。
- 以下是ReentrantLock的使用案例:
- 例子1,lock()的正确使用方法
- 见代码MyLockTest
- 例子2,tryLock()的使用方法
- 见代码MyTryLock
- 例子3,lockInterruptibly()响应中断的使用方法:
- 见代码MyInterruptibly
- ReadWriteLock
- ReadWriteLock也是一个接口,在它里面只定义了两个方法:
- public interface ReadWriteLock {
- /**
- * Returns the lock used for reading.
- *
- * @return the lock used for reading.
- */
- Lock readLock();
- /**
- * Returns the lock used for writing.
- *
- * @return the lock used for writing.
- */
- Lock writeLock();
- }
- 一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作。下面的ReentrantReadWriteLock实现了ReadWriteLock接口。
- ReentrantReadWriteLock
- ReentrantReadWriteLock里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()和writeLock()用来获取读锁和写锁。
- 下面通过几个例子来看一下ReentrantReadWriteLock具体用法。
- 例子1:假如有多个线程要同时进行读操作的话,先看一下synchronized达到的效果
- 见代码MySynchronizedReadWrite
- 例子2:改成用读写锁的话:
- 见代码MyReentrantReadWriteLock
- 注意:
- 不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
- 如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
- Lock和synchronized的选择
- 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
- 2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
- 3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
- 4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
- 5)Lock可以提高多个线程进行读操作的效率。
- 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。
- package cn.itcast_01_mythread.thread.lock;
- /**
- * 一个线程又要读又要写,用synchronize来实现的话,读写操作都只能锁住后一个线程一个线程地进行
- * @author
- *
- */
- public class MySynchronizedReadWrite {
- public static void main(String[] args) {
- final MySynchronizedReadWrite test = new MySynchronizedReadWrite();
- new Thread(){
- public void run() {
- test.get(Thread.currentThread());
- };
- }.start();
- new Thread(){
- public void run() {
- test.get(Thread.currentThread());
- };
- }.start();
- }
- public synchronized void get(Thread thread) {//get方法被锁住synchronized,不管是读还是写同一时刻只能一个线程进来
- long start = System.currentTimeMillis();
- int i=0;
- while(System.currentTimeMillis() - start <= 1) {
- i++;
- if(i%4==0){
- System.out.println(thread.getName()+"正在进行写操作");
- }else {
- System.out.println(thread.getName()+"正在进行读操作");
- }
- }
- System.out.println(thread.getName()+"读写操作完毕");
- }
- }
- package cn.itcast_01_mythread.thread.lock;
- import java.util.concurrent.locks.ReentrantReadWriteLock;
- /**
- * 使用读写锁,可以实现读写分离锁定,读操作并发进行,写操作锁定单个线程。
- *
- * 读跟读不互斥,写跟写互斥,读跟写互斥
- *
- * 如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
- * 如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
- * @author
- *
- */
- public class MyReentrantReadWriteLock {
- private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
- public static void main(String[] args) {
- final MyReentrantReadWriteLock test = new MyReentrantReadWriteLock();
- new Thread(){
- public void run() {//一边读一边写
- test.get(Thread.currentThread());
- test.write(Thread.currentThread());
- };
- }.start();
- new Thread(){
- public void run() {//一边读一边写
- test.get(Thread.currentThread());
- test.write(Thread.currentThread());
- };
- }.start();
- }
- /**
- * 读操作,用读锁来锁定
- * @param thread
- */
- public void get(Thread thread) {
- rwl.readLock().lock();//读操作用读锁锁定
- try {
- long start = System.currentTimeMillis();
- while(System.currentTimeMillis() - start <= 1) {
- System.out.println(thread.getName()+"正在进行读操作");
- }
- System.out.println(thread.getName()+"读操作完毕");
- } finally {
- rwl.readLock().unlock();
- }
- }
- /**
- * 写操作,用写锁来锁定
- * @param thread
- */
- public void write(Thread thread) {
- rwl.writeLock().lock();//写操作用写锁锁定
- try {
- long start = System.currentTimeMillis();
- while(System.currentTimeMillis() - start <= 1) {
- System.out.println(thread.getName()+"正在进行写操作");
- }
- System.out.println(thread.getName()+"写操作完毕");
- } finally {
- rwl.writeLock().unlock();
- }
- }
- }
- //0在读的时候1可以读。0在写的时候别人不可以写。
- /*Thread-0写操作完毕
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作
- Thread-1正在进行写操作*/
hadoop08---读写锁的更多相关文章
- 技术笔记:Delphi多线程应用读写锁
在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...
- java多线程-读写锁
Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...
- 让C#轻松实现读写锁分离
ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...
- C#读写锁ReaderWriterLockSlim的使用
读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对 ...
- 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁
1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...
- 用读写锁三句代码解决多线程并发写入文件 z
C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三 ...
- 锁的封装 读写锁、lock
最近由于项目上面建议使用读写锁,而去除常见的lock锁.然后就按照需求封装了下锁.以简化锁的使用.但是开发C#的童鞋都知道lock关键字用起太方便了,但是lock关键字不支持超时处理.很无奈,为了实现 ...
- Java多线程13:读写锁和两种同步方式的对比
读写锁ReentrantReadWriteLock概述 大型网站中很重要的一块内容就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务 ...
- 让C#轻松实现读写锁分离--封装ReaderWriterLockSlim
ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...
- C#使用读写锁三行代码简单解决多线程并发写入文件时线程同步的问题
(补充:初始化FileStream时使用包含文件共享属性(System.IO.FileShare)的构造函数比使用自定义线程锁更为安全和高效,更多内容可点击参阅) 在开发程序的过程中,难免少不了写入错 ...
随机推荐
- AWT提供了Java Applet 和Java Application中可用的用户图形界面 GUI 中的基本组件
AWT提供了Java Applet 和Java Application中可用的用户图形界面 GUI 中的基本组件( component s). 由于Java是一种独立于平台的 程序设计语言 ,但GUI ...
- noip模拟题题解集
最近做模拟题看到一些好的题及题解. 升格思想: 核电站问题 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定 ...
- ProtocolBuffer在Android端的解析
开题篇 近期公司在使用Protocol Buffer替代原先的json作为移动端的数据交互格式.虽然服务端和CTO把这项新技术吹的天花乱坠,说什么体积小,不易被破解乱七八糟的.可是作为Android端 ...
- ubuntu 用命令行设置chrome的proxy
google-chrome-stable --proxy-server="IP proxy Server:port"
- [转帖收集] Java注解
1.Annotation 它的作用是修饰编程元素.什么是编程元素呢?例如:包.类.构造方法.方法.成员变量等.Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和任何元数据( ...
- HibernateSessionFactory演示样例
package common; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hi ...
- 怎样使用Intent传递对象
怎样使用Intent传递对象 我们能够使用Intent来启动Activity.开启服务Service,发送广播Broadcast,然后使用Intent传递主要的数据类型,如:布尔值,整型,字符串等 I ...
- 修改sudoers权限之后无法sudo的最简单解决方法
网上百度一下进入recovery模式或是单用户模式仍然修改不了sudoers的权限, 后来终于在网上找到了一种最简单的方法,那就是 pkexec chmod 0440 /etc/sudoers
- 调试SVO_edgelet
感谢白巧克力亦唯心提供的SVO_edgelet代码,作者博客:https://blog.csdn.net/heyijia0327/article/details/61682150 程序地址: http ...
- spring + quartz 定时
springConfig配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=& ...