1. 程式人生 > >Java並發(4)

Java並發(4)

環境 訪問 obj 元素 dac app ole 可能 最新

java中的線程安全是什麽: 就是線程同步的意思,就是當一個程序對一個線程安全的方法或者語句進行訪問的時候,其他的不能再對他進行操作了,必須等到這次訪問結束以後才能對這個線程安全的方法進行訪問 什麽叫線程安全: 如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。 或者說:一個類或者程序所提供的接口對於線程來說是原子操作或者多個線程之間的切換不會導致該接口的執行結果存在二義性,也就是說我們不用考慮同步的問題。 線程安全問題都是由全局變量及靜態變量引起的。 若每個線程中對全局變量、靜態變量只有讀操作,而無寫操作,一般來說,這個全局變量是線程安全的;若有多個線程同時執行寫操作,一般都需要考慮線程同步,否則就可能影響線程安全。 看過vector源碼的同學就會知道他的許多操作都是加了synchronized修飾的比如他的添加元素。(不知道synchronized是什麽意思的自行百度!)
1 2 3 public synchronized void addElement(E obj) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; }
而HashMap的所有操作都沒有加synchronized修飾 ,不如他的put源碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for(Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash &&((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
再看看ArrayList的add方法的源碼
1 2 3 4 5 public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
再看StringBuffer的append源碼,他是有synchronized修飾的
1 2 3 4 5 public synchronized StringBuffer append(String str) { super.append(str); return this; }
最後是Properties的setProperty方法,他是有synchronized修飾的
1 2 3 4 5 public synchronized Object setProperty(String key, String value) { return put(key, value); }
由此就可以判斷出誰是線程安全的了 所謂 volatile的措施,就是 1. 每次從內存中取值,不從緩存中什麽的拿值。這就保證了用 volatile修飾的共享變量,每次的更新對於其他線程都是可見的。 2. volatile保證了其他線程的立即可見性,就沒有保證原子性。 3.由於有些時候對 volatile的操作,不會被保存,說明不會造成阻塞。不可用與多線程環境下的計數器 一旦一個共享變量(類的成員變量、類的靜態成員變量)被volatile修飾之後,那麽就具備了兩層語義: 1)保證了不同線程對這個變量進行操作時的可見性,即一個線程修改了某個變量的值,這新值對其他線程來說是立即可見的。 2)禁止進行指令重排序。 volatile只提供了保證訪問該變量時,每次都是從內存中讀取最新值,並不會使用寄存器緩存該值——每次都會從內存中讀取。 而對該變量的修改,volatile並不提供原子性的保證。 由於及時更新,很可能導致另一線程訪問最新變量值,無法跳出循環的情況 多線程下計數器必須使用鎖保護。

Java並發(4)