Java并发编程---lock锁

先了解一下Java.util.concurrent.locks.Lock接口的实现类:ReentrantLockReentrantReadWriteLock的内部类中的ReadLock与WriteLock;分别叫重入锁,读入锁,写入锁。lock必须被显式地创建、锁定和释放,为了可以使用更多的功能,一般用ReentrantLock为其实例化。为了保证锁最终一定会被释放(可能会有异常发生),要把互斥区放在try语句块内,并在finally语句块中释放锁,尤其当有return语句时,return语句必须放在try字句中,以确保unlock()不会过早发生,从而将数据暴露给第二个任务。因此,采用lock加锁和释放锁的一般形式如下:

    @Override
    public void autoMatch(String loanAgreementId, String currentUserId) {
        //加锁 lock效率高
        Lock lock = new ReentrantLock();
        lock.lock();
        try {

            AgreementDomain agreementdomain = agreementService.getPrimaryKeyObj(loanAgreementId);
            ProductDomain product = productService.getPrimaryKeyObj(agreementdomain.getProductId());
            Double actualamount = agreementdomain.getTotalPayment();
            Double serviceCharge = 0d;
            // 检查是否收取服务费
            if (1 == product.getServiceCharge())
                serviceCharge = 500D;
            String uuid = "";
            // 获取排序后的资金池
            List pool = weightCalculation();
            if (pool == null || pool.size() == 0) {
                lending4SeatsBoss(agreementdomain, actualamount, serviceCharge, currentUserId);
            } else {

                for (PartnerAmountModel partneramountmodel : pool) {
                    if (actualamount.compareTo(partneramountmodel.getPartnerRemainingAmount()) < 0)
                        uuid = partneramountmodel.getId();
                    break;
                }

                if (StringUtils.isNotBlank(uuid) == true) {
                    partnerLendingMapper.insert(partnerlending);
                    agreement.setUpdateTime(new Date());
                    agreement.setUpdaterId(currentUserId);
                    agreementService.update(agreement);

                }
            }
        } finally {
            lock.unlock(); // 锁必须在finally块中释放
        }
    }

ReetrantLock有两种锁:忽略中断锁和响应中断锁。忽略中断锁与synchronized实现的互斥锁一样,不能响应中断,而响应中断锁可以响应中断。
如果某一线程A正在执行锁中的代码,另一线程B正在等待获取该锁,可能由于等待时间过长,线程B不想等待了,想先处理其他事情,我们可以让它中断自己或者在别的线程中中断它,如果此时ReetrantLock提供的是忽略中断锁,则它不会去理会该中断,而是让线程B继续等待,而如果此时ReetrantLock提供的是响应中断锁,那么它便会处理中断,让线程B放弃等待,转而去处理其他事情。

读写锁

另外,synchronized获取的互斥锁不仅互斥读写操作、写写操作,还互斥读读操作,而读读操作时不会带来数据竞争的,因此对对读读操作也互斥的话,会降低性能。Java5中提供了读写锁,它将读锁和写锁分离,使得读读操作不互斥,获取读锁和写锁的一般形式如下:

ReadWriteLock rl= new ReentrantReadWriteLock();  
//获取写锁
rl.writeLock().lock() ;
//获取读锁
rl.readLock().lock() ;

你可能感兴趣的:(Java并发编程---lock锁)