浅谈Java并发编程系列(五)—— ReentrantLock VS synchronized

ReentrantLock是Java并发包中一个非常有用的组件,一些并发集合类也是用ReentrantLock实现,包括ConcurrentHashMap。ReentrantLock具有三个特性:等待可中断、可实现公平锁、以及锁可以绑定多个条件。

Java中的ReentrantLock

ReentrantLock与synchronized关键字一样,属于互斥锁,synchronized中的锁是非公平的(公平锁是指多个线程等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁),ReentrantLock默认情况下也是非公平的,但可以通过带布尔值的构造函数要求使用公平锁。线程通过ReentrantLock的lock()方法获得锁,用unlock()方法释放锁。

ReentrantLock和synchronized关键字的区别

  1. ReentrantLock在等待锁时可以使用lockInterruptibly()方法选择中断, 改为处理其他事情,而synchronized关键字,线程需要一直等待下去。同样的,tryLock()方法可以设置超时时间,用于在超时时间内一直获取不到锁时进行中断。

  2. ReentrantLock可以实现公平锁,而synchronized的锁是非公平的。

  3. ReentrantLock拥有方便的方法用于获取正在等待锁的线程。

  4. ReentrantLock可以同时绑定多个Condition对象,而synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含的条件,如果要和多于一个条件关联时,只能再加一个额外的锁,而ReentrantLock只需要多次调用newCondition方法即可。

性能比较

在JDK1.6之前,ReentrantLock的性能要明显优于synchronized,但是JDK1.6中加入了很多针对锁的优化措施,synchronized和ReentrantLock的性能基本完全持平了。

ReentrantLock缺点

ReentrantLock的主要缺点是方法需要置于try-finally块中,另外,开发人员需要负责获取和释放锁,而开发人员常常忘记在finally中释放锁。

ReentrantLock和synchronized示例

import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Java program to show, how to use ReentrantLock in Java.
 * Reentrant lock is an alternative way of locking
 * apart from implicit locking provided by synchronized keyword in Java.
 *
 * @author  Javin Paul
 */
public class ReentrantLockHowto {

    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

     //Locking using Lock and ReentrantLock
     public int getCount() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " gets Count: " + count);
            return count++;
        } finally {
            lock.unlock();
        }
     }

     //Implicit locking using synchronized keyword
     public synchronized int getCountTwo() {
            return count++;
     }



    public static void main(String args[]) {
        final ThreadTest counter = new ThreadTest();
        Thread t1 = new Thread() {

            @Override
            public void run() {
                while (counter.getCount() < 6) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();                    }
                }
            }
        };

        Thread t2 = new Thread() {

            @Override
            public void run() {
                while (counter.getCount() < 6) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        };

        t1.start();
        t2.start();

    }
}

Output:
Thread-0 gets Count: 0
Thread-1 gets Count: 1
Thread-1 gets Count: 2
Thread-0 gets Count: 3
Thread-1 gets Count: 4
Thread-0 gets Count: 5
Thread-0 gets Count: 6
Thread-1 gets Count: 7


Read more: http://javarevisited.blogspot.com/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html#ixzz4DdUHI57e
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值