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---读写锁的更多相关文章

  1. 技术笔记:Delphi多线程应用读写锁

    在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...

  2. java多线程-读写锁

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

  3. 让C#轻松实现读写锁分离

    ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...

  4. C#读写锁ReaderWriterLockSlim的使用

    读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对 ...

  5. 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁

    1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...

  6. 用读写锁三句代码解决多线程并发写入文件 z

    C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三 ...

  7. 锁的封装 读写锁、lock

    最近由于项目上面建议使用读写锁,而去除常见的lock锁.然后就按照需求封装了下锁.以简化锁的使用.但是开发C#的童鞋都知道lock关键字用起太方便了,但是lock关键字不支持超时处理.很无奈,为了实现 ...

  8. Java多线程13:读写锁和两种同步方式的对比

    读写锁ReentrantReadWriteLock概述 大型网站中很重要的一块内容就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务 ...

  9. 让C#轻松实现读写锁分离--封装ReaderWriterLockSlim

    ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...

  10. C#使用读写锁三行代码简单解决多线程并发写入文件时线程同步的问题

    (补充:初始化FileStream时使用包含文件共享属性(System.IO.FileShare)的构造函数比使用自定义线程锁更为安全和高效,更多内容可点击参阅) 在开发程序的过程中,难免少不了写入错 ...

随机推荐

  1. Kmeans原理与实现

    原理 http://www.cnblogs.com/jerrylead/archive/2011/04/06/2006910.html 实现 http://www.cnblogs.com/zjutzz ...

  2. 第一百四十一节,JavaScript,封装库--DOM加载

    JavaScript,封装库--DOM加载 DOM加载,跨浏览器封装DOM加载,当网页文档结构加载完毕后执行函数,不等待图片音频视频等文件加载完毕 /** dom_jia_zai()函数,DOM页面加 ...

  3. 下面的那一个不属于MVC模式中的对象?

    下面的那一个不属于MVC模式中的对象? A. Model B. View C. Collection D. Controller 解答:C MVC是三个单词的缩写,分别为: 模型(Model),视图( ...

  4. ACM/ICPC Moscow Prefinal 2019 趣题记录

    ### Day1: ### **Problem C:** 设$k_i​$为$[A, B]​$中二进制第$i​$位是1的数的个数. 给出$k_0 \cdots k_{63}​$, 求出$[A, B]​$ ...

  5. Sql server不同数据类型间拼接(+)

    )+'m' 输出 4m 若 +'m' 输出:在将 varchar 值 'm' 转换成数据类型 int 时失败.  

  6. .NET中的枚举用法浅析

    本文简单分析了.NET中的枚举用法.分享给大家供大家参考.具体分析如下: 我理解的枚举就是编程中约定的一个“可选值”:例如QQ的在线状态,分别有    在线,Q我吧,隐身,忙碌等等...我觉得这就是一 ...

  7. Asp.net控制Tomcat启动关闭的实现方法

    一.场景 近日有个项目客户要求能自己配置相关权限.由于历史原因这个项目采用的是公司以前的权限系统.这个权限系统很强大,不过有个弊端,就是每增加一个权限菜单都要重启才能生效,不然就要等1天它缓存过期后才 ...

  8. java 连接mariadb 无法获取数据源的问题,在ubuntu上部署的时候(原创)

    问题: 连接数据库时报错: log4j:WARN No appenders could be found for logger (com.mchange.v2.log.MLog).log4j:WARN ...

  9. OpenSSL Heart Bleed 如何修复

     一 . 前言  这两天这个事件沸沸扬扬啊,有了这个bug黑客在电脑前动动手指就能获取各大电商网站.各大银行用户的用户名和密码了,屌爆了 BUG具体内容 : http://heartbleed.com ...

  10. std::stringstream(2)

    stringstream本身的复制构造函数是私有的,无法直接用,于是带来了一些复杂的问题 网上,流传着几种办法,如streamA.str(streamB.str()),但这种办法,复制的仅仅是初始化时 ...