Lock类除了提供了ReentrantLock
的锁以外,还提供了ReentrantReadWriteLock
的锁。读写锁分成两个锁,一个锁是读锁,一个锁是写锁。读锁与读锁之间是共享的,读锁与写锁之间是互斥的,写锁与写锁之间也是互斥的。
看下面的读读共享的例子:
public class ReadReadService {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read(){
try{
try{
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName() +
" " + System.currentTimeMillis());
Thread.sleep(1000 * 10);
}finally {
lock.readLock().unlock();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
测试的代码和结果如下:
ReadReadService service = new ReadReadService();
Thread a = new Thread(service::read);
a.setName("A");
Thread b = new Thread(service::read);
b.setName("B");
a.start();
b.start();
结果如下:
获得读锁A 1485614976979
获得读锁B 1485614976981
两个线程几乎同时执行同步代码。
下面的例子是写写互斥的例子
public class WriteWriteService {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void write(){
try{
try{
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName() +
" " +System.currentTimeMillis());
Thread.sleep(1000 * 10);
}finally {
lock.writeLock().unlock();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
测试代码和结果如下:
WriteWriteService service = new WriteWriteService();
Thread a = new Thread(service::write);
a.setName("A");
Thread b = new Thread(service::write);
b.setName("B");
a.start();
b.start();
Thread.sleep(1000 * 30);
结果如下:
获得写锁A 1485615316519
获得写锁B 1485615326524
两个线程同步执行代码
读写互斥的例子:
public class WriteReadService {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read(){
try{
try{
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(1000 * 10);
}finally {
lock.readLock().unlock();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void write(){
try{
try{
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(1000 * 10);
}finally {
lock.writeLock().unlock();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
测试的代码如下:
WriteReadService service = new WriteReadService();
Thread a = new Thread(service::write);
a.setName("A");
a.start();
Thread.sleep(1000);
Thread b = new Thread(service::read);
b.setName("B");
b.start();
Thread.sleep(1000 * 30);
结果如下:
获得写锁A 1485615633790
获得读锁B 1485615643792
两个线程读写之间也是同步执行代码。