线程安全性

2019-03-19  本文已影响0人  王龙江_3c83

1. 线程安全性

1.1 定义

1.2 原子性

1.2.1 定义

提供了互斥访问,同一时刻(时间段)只能有一个线程对它进行操作。避免脏读:数据读取过程中发生了写操作,数据发生了改变。

1.2.2 实现方法

1.2.2.1 synchronized

同一对象同时只能被 synchronized 一次。

1.2.2.2 ReentrantLock

1.2.2.3 ReentrantReadWriteLock

1.2.2.4 StampedLock

1.2.2.4.1 功能

读写锁虽然实现了读和读的并发,但读写之间是冲突的。

1.2.2.4.2 使用步骤

1.2.2.5 CAS

public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }
// var1 this
// var2 valueOffset
// var4 1
public final int getAndAddInt(Object var1, long var2, int var4) {
        // var5 变量当前值
        int var5;
        //如果变量当前值
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }
// 
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
if (var4 == var1.get(var1,var2)) {
    var4 = var5
    return true;
} else {
    return false;
} 

1.3 可见性

1.3.1 定义

一个线程对主内存的修改可以及时被其他线程观察到,例如取款和余额查询业务。

1.3.2 实现方法

如果没有 violate ,可能当前线程看似完成了赋值操作(即运行到下一步),但数据没同步进主存。

1.4 有序性

1.4.1 定义

一个线程观察其他线程的执行,由于指令重排序的存在,该观察结果一般杂乱无序。

1.4.2 实现方法

1.4.2.1 happens-before 原则

2. 线程安全策略

2.1 不可变对象

2.1.1 final 关键字

2.2 线程封闭

2.2.1 ThreadLocal

2.2.1.1 定义

将对象封装到一个线程中,只有该线程能访问该对象。

2.2.1.2 实现步骤

public class Thread implements Runnable {
    ......
    ThreadLocal.ThreadLocalMap threadLocals = null;
    ......
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();
    }
ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

2.2.1.3 使用步骤

2.3 线程安全对象

2.3.1 定义

为了省略对于线程不安全类的并发访问需要进行的同步处理。

2.3.2 实现方法

2.3.2.1

2.3.2.2

2.3.2.3 AutomicXXX

线程安全,使用 CAS 实现。

2.4 被守护对象

2.4.1 定义

(lock、synchorized),对于共享变量的修改和读取使用锁或同步机制。

2.4.2 实现方法

参考本文章节 1.2.2。

参考资料

上一篇 下一篇

猜你喜欢

热点阅读