在JDK中提供了一种读写锁ReetrantReadWriteLock类,使用它可以加快运行效率,在某些不需要操作实例变量的方法中,完全可以使用读写锁ReetrantReadWriteLock来提升该方法的代码运行速度。
读写锁也有2个锁,一个是读操作相关的锁,也称为共享锁;另一个是写操作相关的锁,也叫排他锁。也就是多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。在没有线程Thread进行写入操作时,进行读取操作的多个Thread都可以获取读锁,而进行写入操作Thread只有在获取写锁后才能进入写入操作。即多个Thread可以同时进行读取操作,但是同一时刻只允许一个Thread进行写入操作。
package service;
importjava.util.concurrent.locks.ReentrantReadWriteLock;
public class Service {
privateReentrantReadWriteLock lock = new ReentrantReadWriteLock();
publicvoid read() {
try{
try{
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+" " + System.currentTimeMillis());
Thread.sleep(10000);
}finally {
lock.readLock().unlock();
}
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
新建ThreadA.java :
package extthread;
import service.Service;
public class ThreadA extends Thread {
privateService service;
publicThreadA(Service service) {
super();
this.service= service;
}
@Override
publicvoid run() {
service.read();
}
}
新建ThreadB.java :
package extthread;
import service.Service;
public class ThreadB extends Thread {
privateService service;
publicThreadB(Service service) {
super();
this.service= service;
}
@Override
publicvoid run() {
service.read();
}
}
新建Run.java :
package test;
import service.Service;
import extthread.ThreadA;
import extthread.ThreadB;
public class Run {
publicstatic void main(String[] args) {
Serviceservice = new Service();
ThreadAa = new ThreadA(service);
a.setName("A");
ThreadBb = new ThreadB(service);
b.setName("B");
a.start();
b.start();
}
}
运行结果:
从控制台打印时间来看,2个线程几乎同时进入了lock()方法后面的代码,说明在使用了lock.readLock()读锁可以提高程序运行效率,允许多个线程同时执行lock()方法后面的代码。
新建Service.java :
package service;
importjava.util.concurrent.locks.ReentrantReadWriteLock;
public class Service {
privateReentrantReadWriteLock lock = new ReentrantReadWriteLock();
publicvoid write() {
try{
try{
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName()
+" " + System.currentTimeMillis());
Thread.sleep(10000);
}finally {
lock.writeLock().unlock();
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
其他类和上面的一样。
程序运行结果:
使用写锁代码lock.writeLock()的效果就是同一时间只允许一个线程执行lock()后面的代码。
修改Service.java:
package service;
importjava.util.concurrent.locks.ReentrantReadWriteLock;
public class Service {
privateReentrantReadWriteLock lock = new ReentrantReadWriteLock();
publicvoid read() {
try{
try{
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+" " + System.currentTimeMillis());
Thread.sleep(10000);
}finally {
lock.readLock().unlock();
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
publicvoid write() {
try{
try{
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName()
+" " + System.currentTimeMillis());
Thread.sleep(10000);
}finally {
lock.writeLock().unlock();
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
新建Run.java :
package test;
import service.Service;
import extthread.ThreadA;
import extthread.ThreadB;
public class Run {
publicstatic void main(String[] args) throws InterruptedException {
Serviceservice = new Service();
ThreadAa = new ThreadA(service);
a.setName("A");
a.start();
Thread.sleep(1000);
ThreadBb = new ThreadB(service);
b.setName("B");
b.start();
}
}
运行结果如下:
由此可见,读写操作时互斥的,只要出现写操作过程,就是互斥的。