面试题-- 什么是偏向锁

所谓的偏向,就是偏心,即锁会偏向于当前已经占有锁的线程 。

大部分情况是没有竞争的(某个同步块大多数情况都不会出现多线程同时竞争锁),所以可以通过偏向来提高性能。即在无竞争时,之前获得锁的线程再次获得锁时,会判断是否偏向锁指向我,那么该线程将不用再次获得锁,直接就可以进入同步块。

偏向锁的实施就是将对象头Mark的标记设置为偏向,并将线程ID写入对象头Mark

当其他线程请求相同的锁时,偏向模式结束

JVM默认启用偏向锁 -XX:+UseBiasedLocking

在竞争激烈的场合,偏向锁会增加系统负担(每次都要加一次是否偏向的判断)

代码例子

public class TestUseBisaedUsing {
    public static List<Integer> numberList = new Vector<Integer>();
    public static void main(String[] args) throws InterruptedException {
        long begin = System.currentTimeMillis();
        int count = 0;
        int startnum = 0;
        while (count < 10000000) {
            numberList.add(startnum);
            startnum += 2;
            count++;
        }
        long end = System.currentTimeMillis();
        System.out.println(end - begin);
    }

Vector是一个线程安全的类,内部使用了锁机制。每次add都会进行锁请求。上述代码只有main一个线程再反复add请求锁。

使用如下的JVM参数来设置偏向锁:

-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0

BiasedLockingStartupDelay表示系统启动几秒钟后启用偏向锁。默认为4秒,原因在于,系统刚启动时,一般数据竞争是比较激烈的,此时启用偏向锁会降低性能。

由于这里为了测试偏向锁的性能,所以把延迟偏向锁的时间设置为0。

可以看到运行时间为423ms

下面关闭偏向锁:

-XX:-UseBiasedLocking

输出699ms

一般在无竞争时,启用偏向锁性能会提高5%左右。

经验分享 程序员 微信小程序 职场和发展