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. UFLDL深度学习笔记 (二)SoftMax 回归(矩阵化推导)

    UFLDL深度学习笔记 (二)Softmax 回归 本文为学习"UFLDL Softmax回归"的笔记与代码实现,文中略过了对代价函数求偏导的过程,本篇笔记主要补充求偏导步骤的详细 ...

  2. C++ namespace浅析

    有一些C语言的基础,突然想看看C++,在Codeblocks上新建工程的时候会生成一个打印"Hello World"的程序,和C语言些许不同.其中最突出的就是"using ...

  3. Class.forName(String className)这个方法的作用

    Class.forName(String className)这个方法的作用 解答:通过类的全名获得该类的类对象

  4. 【SVM】清晰明了的理论文章

    http://www.cnblogs.com/jerrylead/archive/2011/03/13/1982639.html 松弛变量和惩罚因子: http://blog.csdn.net/yan ...

  5. WPF之路——用户控件对比自定义控件UserControl VS CustomControl)

    将多个现有的控件组合成一个可重用的“组”. 由一个XAML文件和一个后台代码文件. 不能使用样式和模板. 继承自UserControl类. 自定义控件(扩展) 在现有的控件上进行扩展,增加一些新的属性 ...

  6. ASP.NET动态增加HTML元素的方法实例小结

    本文实例讲述了ASP.NET动态增加HTML元素的方法.分享给大家供大家参考,具体如下: 在使用asp.net进行web开发的时候页面中的<head></head>中的信息可以 ...

  7. Django admin 的 9 个技巧

    Tip 1:Django admin 后台不限于用 Django 开发的网站 虽然 Django admin 管理界面可以非常友好的用在 Django 项目的其它部分,它同样可以很容易用于其它像传统的 ...

  8. 高质量JavaScript代码

    才华横溢的Stoyan Stefanov,在他写的由O’Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会 ...

  9. python中函数参数*args和**kw的区别

    1.函数与参数(实参) 在python中创建函数是def,创建函数名是def f(),f函数名字,def f(a,b),这里的a,b是两个参数,函数名是自定义的,参数也是自定义,随意就好.看图如下效果 ...

  10. Domino移动Web上传的附件到RichText域

    只是从网上拷贝下来,没有测试. 得到上传文件的路径http://searchdomino.techtarget.com/tip/Trap-an-attachment-path-via-the-Domi ...