多线程编程-ReentrantReadWriteLock(八)
2018-01-19 15:50
288 查看
ReentrantReadWriteLock类1,ReentrantLock类具有完全互斥排他的效果,即同一时刻只有一个线程在执行ReentrantLock().lock()方法后面的代码。这样做虽然保证了实例变量的线程安全性,到时效率较低。ReentrantReadWriteLock类,包括两个锁,一个是读操作相关的锁,也称共享锁;另一个是写操作相关的锁,也称排他锁。多个读锁之间不互斥,读锁和写锁互斥,写锁与写锁互斥。在没有线程进行写操作时,进行读操作的多个线程都可以获取读锁,而进行写操作的线程只有在获取写锁后才能进行写操作。多个线程可以同时进行读,但是同一时刻只能有一个线程进行写操作。测试代码:public class MyService {
private ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
public void readMethod(){
try {
rwlock.readLock().lock();
System.out.println("get read lock ,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("release read lock,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
}catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwlock.readLock().unlock();
System.out.println("readMethod(),release lock.ThreadName="+Thread.currentThread().getName());
}
}
public void writeMethod(){
try {
rwlock.writeLock().lock();
System.out.println("get write lock ,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("release write lock,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
}catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwlock.writeLock().unlock();
System.out.println("writeMethod(),release lock.ThreadName="+Thread.currentThread().getName());
}
}
}
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ta.start();
ThreadB tb = new ThreadB(service);
tb.setName("B");
tb.start();
Thread.sleep(100);
}
}运行结果:get read lock ,ThreadName=A,time=1516347995310
get read lock ,ThreadName=B,time=1516347995310
release read lock,ThreadName=B,time=1516347997310
readMethod(),release lock.ThreadName=B
release read lock,ThreadName=A,time=1516347997310
readMethod(),release lock.ThreadName=A
两个线程几乎同时进入读方法(readLock().lock()后面的代码)。
2,写写互斥
修改上面的代码,两个线程的run方法,都调用writeMethod()方法,
运行结果:
get write lock ,ThreadName=A,time=1516348496480
release write lock,ThreadName=A,time=1516348498480
get write lock ,ThreadName=B,time=1516348498480
writeMethod(),release lock.ThreadName=A
release write lock,ThreadName=B,time=1516348500480
writeMethod(),release lock.ThreadName=B
writeMethod()在两个线程中是顺序执行的。只有其中一个线程释放锁,另一个线程才能获取锁。
3,读写互斥,
修改上面的代码,一个线程的run方法调用readMethod(),另一个线程的run中调用writeMethod()方法,
运行结果:
get read lock ,ThreadName=A,time=1516348717574
release read lock,ThreadName=A,time=1516348719575
get write lock ,ThreadName=B,time=1516348719575
readMethod(),release lock.ThreadName=A
release write lock,ThreadName=B,time=1516348721576
writeMethod(),release lock.ThreadName=B
可以看到两个方法的执行依然是顺序的,只有其中一个线程释放锁,另一个线程才能获取锁。
private ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
public void readMethod(){
try {
rwlock.readLock().lock();
System.out.println("get read lock ,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("release read lock,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
}catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwlock.readLock().unlock();
System.out.println("readMethod(),release lock.ThreadName="+Thread.currentThread().getName());
}
}
public void writeMethod(){
try {
rwlock.writeLock().lock();
System.out.println("get write lock ,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("release write lock,ThreadName="+Thread.currentThread().getName()
+",time="+System.currentTimeMillis());
}catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwlock.writeLock().unlock();
System.out.println("writeMethod(),release lock.ThreadName="+Thread.currentThread().getName());
}
}
}
public class ThreadA extends Thread { private MyService service; public ThreadA(MyService service){ this.service = service; } @Override public void run() { service.readMethod(); } }
public class ThreadB extends Thread { private MyService service; public ThreadB(MyService service){ this.service = service; } @Override public void run() { service.readMethod(); } }public class RunTest {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ta.start();
ThreadB tb = new ThreadB(service);
tb.setName("B");
tb.start();
Thread.sleep(100);
}
}运行结果:get read lock ,ThreadName=A,time=1516347995310
get read lock ,ThreadName=B,time=1516347995310
release read lock,ThreadName=B,time=1516347997310
readMethod(),release lock.ThreadName=B
release read lock,ThreadName=A,time=1516347997310
readMethod(),release lock.ThreadName=A
两个线程几乎同时进入读方法(readLock().lock()后面的代码)。
2,写写互斥
修改上面的代码,两个线程的run方法,都调用writeMethod()方法,
运行结果:
get write lock ,ThreadName=A,time=1516348496480
release write lock,ThreadName=A,time=1516348498480
get write lock ,ThreadName=B,time=1516348498480
writeMethod(),release lock.ThreadName=A
release write lock,ThreadName=B,time=1516348500480
writeMethod(),release lock.ThreadName=B
writeMethod()在两个线程中是顺序执行的。只有其中一个线程释放锁,另一个线程才能获取锁。
3,读写互斥,
修改上面的代码,一个线程的run方法调用readMethod(),另一个线程的run中调用writeMethod()方法,
运行结果:
get read lock ,ThreadName=A,time=1516348717574
release read lock,ThreadName=A,time=1516348719575
get write lock ,ThreadName=B,time=1516348719575
readMethod(),release lock.ThreadName=A
release write lock,ThreadName=B,time=1516348721576
writeMethod(),release lock.ThreadName=B
可以看到两个方法的执行依然是顺序的,只有其中一个线程释放锁,另一个线程才能获取锁。
相关文章推荐
- 多线程编程之ReentrantReadWriteLock
- JAVA多线程之——读写锁 ReentrantReadWriteLock
- Java多线程synchronized、ReentrantLock、ReentrantReadWriteLock 和StampedLock 的对比
- Java多线程学习笔记3——ReentranLock和ReentrantReadWriteLock
- java多线程学习笔记——读写锁(ReentrantReadWriteLock)
- Java多线程——锁(Synchronized、Lock、ReentrantLock、ReadWriteLock、ReentrantReadWriteLock)
- java多线程学习10-使用ReentrantReadWriteLock的一个例子
- 多线程锁的使用(ReentrantLock/Condition/ReentrantReadWriteLock)
- java多线程基础---synchronized与ReentrantReadWriteLock的介绍与比较
- java 多线程 ReentrantReadWriteLock 使用
- 并发编程实践六:ReentrantReadWriteLock
- 多线程之ReentrantReadWriteLock
- JAVA多线程之——读写锁 ReentrantReadWriteLock
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
- java多线程--ReentrantReadWriteLock的使用
- 【Java多线程】ReentrantReadWriteLock
- java多线程编程——显示锁ReadWriteLock(二)
- JAVA多线程之——读写锁 ReentrantReadWriteLock
- C# 多线程编程之锁的使用【互斥锁(lock)和读写锁(ReadWriteLock)】
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock