synchronized与ReentrantLock的区别

这是一个老生常谈的问题,可是若是仅仅是那些比较广泛的说法,我也不用记录这篇文章,今天在写二者代码的时候还有一个不容易发现到的区别点。bash

常规区别

  • ReentrantLock更加灵活,提供了超时获取锁,可中断锁。提供了非公平锁和非公平锁,而synchronized仅仅是非公平锁。
  • 用法上,ReentrantLock必须手动释放锁,而且只能修饰代码块。而synchronized不用手动释放锁,除此以外能够修饰方法。

还有一个区别是使用synchronized的线程会被block住,而ReentrantLock的线程则是进入waiting状态ide

疑问点

ReentrantLock真的比synchronized性能高吗?性能

我写了一个简单的demo测试

public class LockDemo {

    static ReentrantLock lock = new ReentrantLock(false);

    public static void main(String[] args) {
        syncTest();
		 //分别测试
//        lockTest();
    }


    public static void syncTest() {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println(Thread.currentThread().getName() + "开始锁定");
                        try {
                            Thread.sleep(2 * 1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            System.out.println(Thread.currentThread().getName() + "解锁");

                        }
                    }
                }
            }.start();
        }
    }

    public static void lockTest() {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + "开始锁定");
                    try {
                        Thread.sleep(2 * 1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println(Thread.currentThread().getName() + "解锁");
                        lock.unlock();
                    }
                }
            }.start();
        }
    }

}

复制代码

运行的结果以下:优化

Synchonized,其线程状态只有time_waiting与blocked,当获取到锁的线程执行完毕以后,其他线程会一块儿再次争抢锁spa

image-20190504181956547

image-20190504182035887

ReentrantLock的非公平锁测试,尽管我用的是非公平锁,可是看起来仍是有公平性的。其内部线程进入的是waiting状态线程

image-20190504182246124

image-20190504182334411

至因而否性能是高点,我以为单个线程去获取锁会比多个线程一块儿去抢锁性能会高一些吧,synchronized对锁作的优化也只是在单线程以及两个线程的时候作的优化,一旦升级为重量级锁,那些优化也就没有效果了。code

固然这是我的猜想。cdn

最后

这里其实看ReentrantLock内部的源码能够看到细节。blog

  • Locksupport.park,线程会进入waiting状态
  • ReentrantLock尽管使用的是非公平锁,可是若是有新的线程尝试获取到锁的时候,只有当前的线程会去争抢锁。
相关文章
相关标签/搜索