`
pi88dian88
  • 浏览: 40545 次
  • 性别: 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读写锁

    然而,与内置锁不同的是,使用ReentrantLock需要显式调用`lock()`和`unlock()`方法来获取和释放锁,这增加了更多的控制和高级功能。 ReentrantLock实现了Lock接口,提供了以下几个关键方法: 1. `lock()`: 阻塞直到...

    基于Java并发编程的多线程同步与锁机制.zip

    本项目旨在深入探讨Java并发编程中的多线程同步与锁机制,涵盖了从基础的线程创建、同步方法到高级的并发工具类如ReentrantLock、ReadWriteLock、Atomic类等的使用。通过一系列的示例代码和详细的文档说明,帮助...

    JUC面试知识点手册快速版

    3.1 ReentrantLock 3.2 ReadWriteLock 3.3 StampedLock 第四章:同步辅助工具 4.1 CountDownLatch 4.2 CyclicBarrier 4.3 Semaphore 4.4 Exchanger 第五章:原子类和无锁编程 5.1 AtomicInteger与...

    基于Java多线程与线程安全实践(源码+使用文档)

    锁机制:包括ReentrantLock、ReadWriteLock等锁的使用示例。 技术架构 Java:作为后端开发的主要语言,Java提供了强大的多线程支持和面向对象编程能力。 JDK多线程库:利用Java Development Kit中的多线程库,如jav

    层次业务模型的同步锁设计

    如果业务逻辑复杂,可能需要使用ReentrantLock,它支持公平锁和非公平锁策略,以及可中断的等待和定时等待,这在处理长时间等待的情况时更为灵活。 对于读多写少的场景,ReadWriteLock(读写锁)可以提高性能。读写...

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

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

    23 按需上锁—ReadWriteLock详解.pdf

    使用ReadWriteLock与使用Lock接口的基本流程相似,需要分别获取读锁和写锁。以下是一个简单的例子: ```java public class Client { public static void main(String[] args) throws InterruptedException { ...

    深入java并发编程,使用ReentrantLock和 Synchronized加锁

    3. **锁分离**:ReentrantLock支持锁的分离,即读写锁(`ReadWriteLock`),允许多个线程同时读取,但写操作是独占的,提高并发性能。 4. **中断支持**:持有锁的线程可以通过`interrupt()`方法中断等待锁的线程,`...

    Java高并发编程与JVM性能调优实战 视频教程 下载下载因为太大存百度云盘2.zip

    2. **并发控制机制**:深入讲解synchronized关键字的用法,包括互斥锁、可重入锁,以及Lock接口和相关的实现如ReentrantLock、ReadWriteLock等。 3. **并发集合**:探讨并发安全的集合框架,如ConcurrentHashMap、...

    Java锁机制详解.pdf

    但如果需要更细粒度的控制或是更好的性能,使用ReentrantLock或是ReadWriteLock可能是更合适的选择。此外,Java并发API中还包括了其他并发工具类,如Semaphore、CountDownLatch以及CyclicBarrier等,这些工具类在...

    面试-Java一些常见面试题+题解之操作系统-OperatingSystem.zip

    3. Lock接口与实现:ReentrantLock、ReadWriteLock、Condition等高级并发工具的使用场景和优势。 4. 并发容器:ArrayList、LinkedList、HashMap、ConcurrentHashMap等容器在多线程环境下的表现和选择依据。 三、...

    Python库 | lockable-0.5.0.tar.gz

    《Python库lockable-0.5.0:掌握并发控制与锁定机制》 在Python编程中,当涉及到多线程或多进程操作时,确保数据安全和一致性是至关重要的。这通常需要利用同步原语,如锁(locks)来管理对共享资源的访问。...

    Java 并发编程实战(高清带目录).zip

    2. **Java并发API**:详细讲解了Java并发库中的关键类和接口,如Thread、Runnable、ExecutorService、Future、Semaphore、CyclicBarrier、CountDownLatch、Exchanger以及Lock(ReentrantLock、ReadWriteLock)等,...

    实战Java高并发程序设计模式视频

    同时,学习ReentrantLock、ReadWriteLock等高级锁的使用场景和优势。 4. **并发集合**:理解并使用并发安全的数据结构,如ConcurrentHashMap、CopyOnWriteArrayList和ConcurrentLinkedQueue,以及它们在并发环境下...

    j2ee.zip_cxf j2ee_java并发

    在本项目中,可能会有多个线程同时访问数据库或处理XML数据,这就需要我们掌握并发控制机制,如synchronized关键字、Lock接口(ReentrantLock、ReadWriteLock等)、并发集合(ConcurrentHashMap、...

    JAVA面试题最新全集

    3. Lock接口:ReentrantLock、ReadWriteLock的实现与使用。 4. 并发工具类:Semaphore、CountDownLatch、CyclicBarrier、Exchanger等。 5. 并发集合:ConcurrentHashMap、ConcurrentLinkedQueue等并发安全的集合。 ...

    阿里巴巴Java开发手册(详尽版)1.4.0.rar

    2. Lock接口:ReentrantLock、ReadWriteLock等高级锁的使用,可以提供更细粒度的锁控制,提升并发性能。 3. CountDownLatch、CyclicBarrier、Semaphore等并发工具类的使用,可以有效地协调多线程间的同步。 四、...

    深入了解性能优化.zip

    理解和掌握线程池的使用、锁的优化(如synchronized、ReentrantLock、ReadWriteLock等)、并发容器的选择(如ConcurrentHashMap、CopyOnWriteArrayList等),以及如何避免死锁、活锁、饥饿等问题,能显著提升系统的...

    java并发编程实践

    书中还特别强调了同步机制,如synchronized关键字、 volatile变量、Lock接口及其实现,以及ReentrantLock、ReadWriteLock等高级锁机制。理解这些同步原语对于确保线程安全和数据一致性至关重要。同时,作者也讨论了...

    JAVA核心面试知识整理(283页).zip

    2. 锁机制:锁接口(ReentrantLock,ReadWriteLock),原子类(AtomicInteger,AtomicReference等)。 3.并发集合:ConcurrentHashMap,CopyOnWriteArrayList,ConcurrentLinkedQueue等。 4. CountDownLatch,...

Global site tag (gtag.js) - Google Analytics