使用ReentrantReadWriteLock类

类ReentrantLock具有完全互斥排他的效果,即同一时刻只有一个线程在执行ReentrantLock.lock()方法后面的任务。这样虽然保证了实例变量的线程安全性,但是效率确实非常低下的。所以在JDK中提供了一种读写锁ReentrantReadWriteLock类,使用它可以加快运行效率,在某些不需要操作实例变量的方法中,完全可以使用读写锁ReentrantReadWriteLock来提升该方法的代码运行速度。

读写锁表示有两种锁,一个是读操作相关的锁,也称为共享锁;另一个是写相关的锁,也称为排它锁。多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。在没有线程进行写入操作时,进行读操作的多个线程都可以获取读锁,而进行写入操作的线程只有在获取写锁后才能进行写入操作。

使用ReentrantReadWriteLock进行同步示例如下:

Service类,持有ReentrantReadWriteLock引用,包含只写和只读的方法,只读方法中用的是读锁,只写方法中用的是写锁。

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class MyService {
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read(){
        try{
            lock.readLock().lock();         //读锁
            System.out.println("获得读锁 "+Thread.currentThread().getName()+" "+System.currentTimeMillis());
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
    }

    public void write(){
        try{
            lock.writeLock().lock();        //写锁
            System.out.println("获得写锁 "+Thread.currentThread().getName()+" "+System.currentTimeMillis());
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }
}

线程A,执行读操作。

public class ThreadA extends Thread{

    private MyService service;

    public ThreadA(MyService service){
        super();
        this.service = service;
    }

    @Override
    public void run(){
        service.read();
    }
}

线程B,执行写操作

public class ThreadB extends Thread{

    private MyService service;

    public ThreadB(MyService service){
        super();
        this.service = service;
    }

    @Override
    public void run(){
        service.write();
    }
}

测试

public class Run {

    public static void main(String[] args) throws InterruptedException {
        MyService service = new MyService();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();
        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }
}

运行结果如下,线程A执行完成之后,线程B才获得锁:

获得读锁 A 1462172338496
获得写锁 B 1462172348497

参考《Java多线程编程核心技术》

 
我的同类文章
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值