您的位置:首页 > 编程语言

多线程编程-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 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

可以看到两个方法的执行依然是顺序的,只有其中一个线程释放锁,另一个线程才能获取锁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: