Synchronized 鎖重入
使用Synchronized的時候,當一個線程獲得一個對象的鎖诚纸,在這個線程里面執(zhí)行代碼時再次請求這個對象的鎖杈曲,就可以直接得到這個對象的鎖。
當一個線程請求另一個線程持有的鎖時剪芥,該線程就會阻塞堤结,而該線程請求自己持有的鎖時旬陡,如果這個鎖是重入鎖,就請求成功锥忿,否則就阻塞虚吟。
一句話總結(jié):自己可以獲取自己內(nèi)部的鎖寸认。
可重入鎖的作用:最大限度的避免死鎖签财。
可重入鎖的其他特性:
- 父子可繼承性
- 出現(xiàn)異常時串慰,鎖自動釋放
- 單利模式-雙重校驗鎖
volatile 與 synchronized 的區(qū)別
volatile關鍵字的作用:強制從公共堆棧中取得變量的值,而不是從線程的私有數(shù)據(jù)棧中取得變量的值唱蒸。
- volatile是線程同步的輕量級實現(xiàn)邦鲫,性能比synchronized好,volatile只能修飾變量神汹,synchronized可以修飾代碼塊庆捺,方法等。
- 多線程訪問volatile不會阻塞屁魏,訪問synchronized會阻塞
- 可以保證數(shù)據(jù)的可見性滔以,但不可以保證原子性,而 synchronized 可以保證原子性氓拼,也可以間接保證可見性你画,因為他會將私有內(nèi)存和公共內(nèi)存中的數(shù)據(jù)做同步抵碟。不能保證原子性,就是不能保證線程安全坏匪。
- volatile 解決的是變量在多個線程之間的可見性拟逮,而 synchronized 解決的是多個線程之間訪問資源的同步性。
ThreadLocal 的介紹與使用
ThreadLocal概述
ThreadLocal的存在是為了解決每個線程都有自己的共享變量适滓,這個變量是線程私有的敦迄。
public class ThreadLocalDemo {
public static ThreadLocal<List<String>> threadLocal = new ThreadLocal<>();
public void setThreadLocal(List<String> values) {
threadLocal.set(values);
}
public void getThreadLocal() {
System.out.println(Thread.currentThread().getName());
threadLocal.get().forEach(name -> System.out.println(name));
}
public static void main(String[] args) throws InterruptedException {
final ThreadLocalDemo threadLocal = new ThreadLocalDemo();
new Thread(() -> {
List<String> params = new ArrayList<>(3);
params.add("張三");
params.add("李四");
params.add("王五");
threadLocal.setThreadLocal(params);
threadLocal.getThreadLocal();
}).start();
new Thread(() -> {
try {
Thread.sleep(1000);
List<String> params = new ArrayList<>(2);
params.add("Chinese");
params.add("English");
threadLocal.setThreadLocal(params);
threadLocal.getThreadLocal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
上面的代碼中有一個靜態(tài)的threadLocal屬性,有兩個線程去同時訪問它凭迹,由于ThreadLocal 修飾罚屋,則不同的線程訪問的就是該線程設置的值。
當使用ThreadLocal維護變量時嗅绸,ThreadLocal為每個使用該變量的線程提供獨立的變量副本沿后,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應的副本朽砰。
ThreadLocal與Synchronized同步機制的比較
在同步機制中尖滚,通過Synchronized對象鎖,可以保證在同一時間只有一個線程訪問變量瞧柔。這個變量是多個線程之間共享的漆弄。
TreadLocal是線程的局部變量,是一種多線程間并發(fā)訪問變量的解決方案造锅。
ThreadLocal 完全不提供鎖撼唾,而使用以空間換時間的方式,為每個線程提供變量的獨立副本哥蔚,以保證線程的安全倒谷。
本文是http://gitbook.cn/gitchat/column/5a24fb14e3a13b7fc5933a44 gitChat線程課的學習總結(jié)筆記。