第四章 锁的优化

2018-03-12  本文已影响0人  icelovesummer

1. 提高锁性能的几点建议

1.1 减小锁持有时间

// 减小锁持有时间可以降低锁冲突的可能性,提升系统并发能力。
public synchronized void syncMethod(){
    otherMethod1(); //不需要同步
    mutextMethod(); //需要同步
    otherMethod2() //不需要同步
}

public void syncMethod(){
    otherMethod1(); //不需要同步
    sychronized(this){
        mutextMethod(); //需要同步
    }
    otherMethod2() //不需要同步
}

1.2 减小锁粒度

1.3 锁分离

private final ReentrantLock takeLock = new ReentrantLock();

/** Wait queue for waiting takes */
private final Condition notEmpty = takeLock.newCondition();

/** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock();

/** Wait queue for waiting puts */
private final Condition notFull = putLock.newCondition();

1.4 锁粗化

//减少锁请求的次数
public void demoMethod(){
    sychronized(lock){
        //do sth
    }
    //other thing which need no lock
    sychronized(lock){
        //do sth
    }
}

public void demoMethod(){
    sychronized(lock){
        //do sth
        //other thing which need no lock
        //do sth
    }
}
//更极端
for(100次循环){
    sychronized(lock){

    }
}
sychronized(lock){
    for(100次循环){
        
    }
}

2. 虚拟机对锁优化所做的努力

2.1 锁偏向

2.2 轻量级锁

2.3 自旋锁

2.4 锁消除

//vector内部含有锁,但是此处的vector是局部变量,分配在虚拟机栈空间,线程私有,不存在竞争。虚拟机会消除这个锁。
//此处涉及逃逸分析。
public String[] createStrings() {
    Vector<String> v = new Vector<>();
    for (int i = 0; i < 100; i++) {
        v.add(Integer.toString(i));
    }
    return v.toArray(new String[] {});
}

3. ThreadLocal

//如果get()方法先于set()方法之前调用,则调用setInitialValue()方法返回初始值。
public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);// getMap方法即去获取当前线程的ThreadLocalMap变量。
    if (map != null)
        map.set(this, value);//以this(ThreadLocal本身)为Key,参数value为值进行保存
    else
        createMap(t, value);
}

public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}

【ThreadLocal是否会造成内存泄露?】

4. 无锁

4.1 CAS算法

4.2 无锁的线程安全整数:AtomicInteger

AtomicInteger4

就内部实现而言,AtomicInteger保存着

private volatile int value;//当前实际取值
private static final long valueOffset;//value在AtomicInteger对象中的偏移量
public class AtomicIntegerDemo {
    static AtomicInteger i = new AtomicInteger(0);  
    public static void main(String[] args) throws InterruptedException {
        Runnable r = ()->{
            for (int k = 0; k < 10000; k++) {
                i.incrementAndGet();
            }
        };
                Thread[] threads = new Thread[10];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(r);
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].join();
        }
        System.out.println(i);
    }
}
//输出100000,说明线程安全的。

incrementAndGet()的实现:无限循环就是CAS

public final int incrementAndGet() {
    for(;;) {
        int current = get();
        int next = current + 1;
        if(compareAndSet(current, next)) {
            return next;
        }
    }
}

4.3 无锁的对象引用:AtomicReference

class Person {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

// 普通引用,多线程下会导致数据不一致,name和age不是一个人
private static Person person;

// 原子性引用
private static AtomicReference<Person> aRperson;

4.4 带时间戳的对象引用:AtomicStampedReference

AtomicStampedReference

4.5 数组无锁:AtomicIntegerArray

AtomicIntegerArray

4.6 让普通变量享受原子操作:AtomicIntegerFieldUpdater

class Candidate{
    int id;
    volatile int score;
}

AtomicIntegerFieldUpdater<Candidate> updater = AtomicIntegerFieldUpdater.newUpdater(Candidate.class, "score");

【注意】

4.7 SynchronousQueue

http://blog.csdn.net/yanyan19880509/article/details/52562039

上一篇 下一篇

猜你喜欢

热点阅读