`
pi88dian88
  • 浏览: 40104 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ReentrantLock与ReadWriteLock的使用

    博客分类:
  • Java
阅读更多

下面的内容基本上来自于《Java并发编程实践》, 留个记录~

 

一, ReentrantLock

ReentrantLock实现了Lock接口,提供了与synchronized 相同的互斥和内存可见性的保证。获得ReentrantLock的锁与进入synchronized 块有着相同的内存语义;释放ReentrantLock锁与退出synchronized块有着相同的内存语义。下面是Lock接口的定义:

 

package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;

public interface Lock {
    //获得锁对象,如果无法获得锁,就会阻塞,直到可以获取
    void lock();
    //获得锁对象,能响应中断,如果无法获得锁,并且没有中断事件,线程阻塞
    void lockInterruptibly() throws InterruptedException;
    //如果能获得锁,则返回true;不能获得锁,返回false,不会阻塞
    boolean tryLock();
    //同上,只是增加锁获取超时限制
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    //释放锁
    void unlock();
    
    Condition newCondition();
}

 为什么要创建与内部锁如此相似的机制呢?因为内部锁有一些功能上的限制---不能中断那些正在等待获取锁的线程,并且在请求锁失败的情况下,必须无限等待。但是使用ReentrantLock需要注意的是 锁必须在finally中释放。使用如下:

ReentrantLock lock = new ReentrantLock();
		...
		lock.lock();
		try {
			//code
		} finally {
			lock.unlock();
		}

 具体使用如下:

public class ReentrantLockTest {
	private ReentrantLock lock = new ReentrantLock();
	private SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");

	public void printA() {
		lock.lock();
		System.out.println(format.format(new Date()) + "---printA");
		try {
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void printB() {
		lock.lock();
		System.out.println(format.format(new Date()) + "---printB");
		try {
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public static class MyThread extends Thread {
		private ReentrantLockTest reentrantLockTest;
		private String methodName;

		public MyThread(ReentrantLockTest reentrantLockTest, String methodName) {
			super();
			this.reentrantLockTest = reentrantLockTest;
			this.methodName = methodName;
		}

		@Override
		public void run() {
			if ("printA".equalsIgnoreCase(methodName))
				reentrantLockTest.printA();
			else
				reentrantLockTest.printB();
		}
	}
	
	public static void main(String[] args) {
		ReentrantLockTest test = new ReentrantLockTest();
		MyThread t1 = new MyThread(test, "printA");
		MyThread t2 = new MyThread(test, "printB");
		t1.start();
		t2.start();
	}
}

 输出的结果如下:

15:34:34---printA
15:34:37---printB

 

 

二, ReadWriteLock

ReadWriteLock: 允许读操作并发执行;不允许“读/写”, “写/写”并发执行。当数据结构需要频繁的读时,ReadWriteLock相比ReentrantLock与synchronized的性能更好。

public class ReadWriteLockTest {
	private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	private SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
	private Lock readLock = readWriteLock.readLock();
	private Lock writeLock = readWriteLock.writeLock();

	public void read() {
		readLock.lock();
		try {
			System.out.println(format.format(new Date()) + "---read---");
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			readLock.unlock();
		}
	}

	public void write() {
		writeLock.lock();
		try {
			System.out.println(format.format(new Date()) + "---write---");
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			writeLock.unlock();
		}
	}

	public static class MyThread extends Thread {
		private ReadWriteLockTest readWriteLockTest;
		private String methodName;

		public MyThread(ReadWriteLockTest readWriteLockTest, String methodName) {
			super();
			this.readWriteLockTest = readWriteLockTest;
			this.methodName = methodName;
		}

		@Override
		public void run() {
			if ("read".equalsIgnoreCase(methodName))
				readWriteLockTest.read();
			else
				readWriteLockTest.write();
		}
	}

	public static void main(String[] args) {
		ReadWriteLockTest test = new ReadWriteLockTest();
		Thread t1 = new MyThread(test, "read");
		Thread t2 = new MyThread(test, "read");
		t1.start();
		t2.start();
	}
}

 当methodName都为read时,输出结果如下:

15:56:25---read---
15:56:25---read---读取操作同时执行

 

当methodName为read/write时,输出结果如下:

15:57:17---write---
15:57:20---read---

读/写同步执行

0
1
分享到:
评论

相关推荐

    Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁

    主要介绍了Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁,本文讲解了ReentrantLock概况、Lock接口、Lock使用、轮询锁的和定时锁、公平性、可中断获锁获取操作等内容,需要的朋友可以参考下

    ideaworker.zip

    博主的多线程文章的测试类-线程创建以及线程控制器 内含创建线程、synchronized、ReentrantLock、ReadWriteLock、CAS、四种引用、并发控制器、volatile

    JUC知识点总结(三)ReentrantLock与ReentrantReadWriteLock源码解析

    8. Lock接口 (ReentrantLock 可重入锁) 特性 ReentantLock 继承接口 Lock 并实现了接口中定义的方法, 它是一种可重入锁, 除了能完成 synchronized 所能完成的所有工作外,还提供了诸如可响应中断锁、可轮询锁...

    locks框架:接口.pdf

    常用 Lock 接口实现类: 详细讲解 Lock 接口的一些常用实现类,如 ReentrantLock、ReadWriteLock、StampedLock 等。解释它们的特点和适用场景。 Lock 接口的基本用法: 深入探讨如何使用 Lock 接口来保护共享资源。...

    关于synchronized、Lock的深入理解

    目录synchronized的缺陷Lock和ReentrantLock常用方法ReadWriteLock和ReentrantReadWriteLockLock和synchronized区别synchronized锁升级公平锁和非公平锁 synchronized的缺陷 众所周知,synchronized锁是JAVA的关键字...

    详解java多线程的同步控制

    目录线程安全 Thread Safety重入锁 ReentrantLock读写锁 ReadWriteLock倒计数器 CountDownLatch循环栅栏 CyclicBarrier信号量 Semaphore 线程安全 Thread Safety JMM JMM(Java Memory Model)是一种基于计算机内存...

    javaSE代码实例

    17.5.2 PriorityQueue类的知识与使用 397 17.5.3 BlockingQueue接口介绍 399 17.6 阻塞的栈操作 401 17.6.1 BlockingDeque接口与LinkedBlockingDeque类简介 401 17.6.2 LinkedBlockingDeque类的具体使用 ...

    JDK_seaswalker.tar.gz

    ReadWriteLock ReentrantLock Socket UDP IO FileChannel Buffer URLConnection NIO Process HashMap LinkedHashMap TreeMap ConcurrentHashMap ConcurrentLinkedQueue ThreadPool ThreadLocal ...

    javaforkjoin源码-gitbook-BAT-interview:本文综合自己在一线互联网工作感悟,经验。记录开源框架的源码解读,数据

    ReadWriteLock源码] [Condition 条件队列和Object.wait队列] 并发同步工具类 [CountDownLatch] [CyclicBarrier] [Semaphore] [Exchanger] Atomic包 并发集合 [BlockQueue] [ArrayBlockingQueue] ...

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段27讲 ReadWriteLock&ReentrantReadWriteLock详细讲解_.mp4  高并发编程第三阶段28讲 Condition初步使用,提出几个疑问_.mp4  高并发编程第三阶段29讲 关于Condition疑问的几个小实验,...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段27讲 ReadWriteLock&ReentrantReadWriteLock详细讲解_.mp4  高并发编程第三阶段28讲 Condition初步使用,提出几个疑问_.mp4  高并发编程第三阶段29讲 关于Condition疑问的几个小实验,...

    java核心知识点整理.pdf

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

Global site tag (gtag.js) - Google Analytics