本文内容部分引自《Java多线程编程核心技术》,感谢作者!!!
代码地址:https://github.com/xianzhixianzhixian/thread.git
ReentrantReardWriteLock类的优势和用法
1、ReentrantLock类中提供了lock.lock()和lock.unlock()来实现获得对象锁和释放对象锁。但是我们可以考虑这样一个问题,当多个线程需要读取而并不需要修改共享变量的数据时,也是一个线程一个线程同步读取的,这样效率就会变低。
2、ReentrantReadWriteLock类提供了读锁和写锁,lock.readLock().lock()、lock.readLock().unlock()、lock.writeLock().lock()和lock.writeLock().unlock()。其中锁与锁之间读读共享、读写互斥、写读互斥、写写互斥,提高了效率。
读写锁用法以及共享互斥情况示例
-
读读共享
Service.java
/**
* ReentrantReadWriteLock类中读读共享
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:45
*/
public class Service {
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void read(){
try {
try {
readWriteLock.readLock().lock();
System.out.println("获得读锁 "+Thread.currentThread().getName()
+" "+System.currentTimeMillis());
Thread.sleep(10000);
} finally {
readWriteLock.readLock().unlock();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ThreadA.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:48
*/
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.read();
}
}
ThreadB.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:48
*/
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
service.read();
}
}
Run.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:49
*/
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA threadA = new ThreadA(service);
threadA.setName("A");
ThreadB threadB = new ThreadB(service);
threadB.setName("B");
threadA.start();
threadB.start();
}
}
运行结果:
-
读写互斥和写读互斥
Service.java
/**
* ReentrantReadWriteLock读写互斥
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:57
*/
public class Service {
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void read(){
try {
try {
readWriteLock.readLock().lock();
System.out.println("获得读锁 "+ Thread.currentThread().getName()
+" "+System.currentTimeMillis());
Thread.sleep(10000);
} finally {
readWriteLock.readLock().unlock();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void write(){
try {
try {
readWriteLock.writeLock().lock();
System.out.println("获得写锁 "+ Thread.currentThread().getName()
+" "+System.currentTimeMillis());
Thread.sleep(10000);
} finally {
readWriteLock.writeLock().unlock();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ThreadA.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:48
*/
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.write();
}
}
ThreadB.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:48
*/
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
service.read();
}
}
Run.java读写互斥
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 21:00
*/
public class Run {
public static void main(String[] args) throws Exception {
Service service = new Service();
ThreadA threadA = new ThreadA(service); //写锁
threadA.setName("A");
ThreadB threadB = new ThreadB(service); //读锁
threadB.setName("B");
threadB.start();
Thread.sleep(100);
threadA.start();
}
}
运行结果:
Run.java写读互斥
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 21:00
*/
public class Run {
public static void main(String[] args) throws Exception {
Service service = new Service();
ThreadA threadA = new ThreadA(service); //写锁
threadA.setName("A");
ThreadB threadB = new ThreadB(service); //读锁
threadB.setName("B");
threadA.start();
Thread.sleep(100);
threadB.start();
}
}
运行结果:
-
写写互斥
Service.java
/**
* ReentrantReadWriteLock类中写写锁互斥
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:51
*/
public class Service {
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void write(){
try {
try {
readWriteLock.writeLock().lock();
System.out.println("获得写锁 "+ Thread.currentThread().getName()
+" "+System.currentTimeMillis());
Thread.sleep(10000);
} finally {
readWriteLock.writeLock().unlock();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ThreadA.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:48
*/
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.write();
}
}
ThreadB.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:48
*/
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
service.write();
}
}
Run.java
/**
* @author: xianzhixianzhixian
* @date: 2019-01-23 20:54
*/
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA threadA = new ThreadA(service);
threadA.setName("A");
ThreadB threadB = new ThreadB(service);
threadB.setName("B");
threadA.start();
threadB.start();
}
}
运行结果: