本文內容部分引自《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();
}
}
運行結果: