本文目錄一覽:
Java中如何保證線程安全性
線程安全主要在體現在這三個方面:
1.原子性:提供互斥訪問,同一時刻只能有一個線程對數據進行操作,(atomic,synchronized);
2.可見性:一個線程對主內存的修改可以及時地被其他線程看到,(synchronized,volatile);
3.有序性:一個線程觀察其他線程中的指令執行順序,由於指令重排序,該觀察結果一般雜亂無序,(happens-before原則)。
所以想保證線性安全的話只要從這三個方面入手就可以了。
Java的List如何實現線程安全?
Java的List如何實現線程安全?
Collections.synchronizedList(names);效率最高,線程安全
Java的List是我們平時很常用的集合,線程安全對於高並發的場景也十分的重要,那麼List如何才能實現線程安全呢 ?
加鎖
首先大家會想到用Vector,這裡我們就不討論了,首先討論的是加鎖,例如下面的代碼
public class Synchronized{
private ListString names = new LinkedList();
public synchronized void addName(String name ){
names.add(“abc”);
}
public String getName(Integer index){
Lock lock =new ReentrantLock();
lock.lock();
try {
return names.get(index);
}catch (Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
return null;
}
}
synchronized一加,或者使用lock 可以實現線程安全,但是這樣的List要是很多個,代碼量會大大增加。
java自帶類
在java中我找到自帶有兩種方法
CopyOnWriteArrayList
CopyOnWrite 寫入時複製,它使一個List同步的替代品,通常情況下提供了更好的並發性,並且避免了再迭代時候對容器的加鎖和複製。通常更適合用於迭代,在多插入的情況下由於多次的複製性能會一定的下降。
下面是add方法的源代碼
public boolean add(E e) {
final ReentrantLock lock = this.lock; // 加鎖 只允許獲得鎖的線程訪問
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
// 創建個長度加1的數組並複製過去
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e; // 賦值
setArray(newElements); // 設置內部的數組
return true;
} finally {
lock.unlock();
}
}
Collections.synchronizedList
Collections中有許多這個系列的方法例如
主要是利用了裝飾者模式對傳入的集合進行調用 Collotions中有內部類SynchronizedList
static class SynchronizedListE
extends SynchronizedCollectionE
implements ListE {
private static final long serialVersionUID = -7754090372962971524L;
final ListE list;
SynchronizedList(ListE list) {
super(list);
this.list = list;
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
static class SynchronizedCollectionE implements CollectionE, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
final CollectionE c; // Backing Collection
final Object mutex; // Object on which to synchronize
這裡上面的mutex就是鎖的對象 在構建時候可以指定鎖的對象 主要使用synchronize關鍵字實現線程安全
/**
* @serial include
*/
static class SynchronizedListE
extends SynchronizedCollectionE
implements ListE {
private static final long serialVersionUID = -7754090372962971524L;
final ListE list;
SynchronizedList(ListE list) {
super(list);
this.list = list;
}
SynchronizedList(ListE list, Object mutex) {
super(list, mutex);
this.list = list;
}
這裡只是列舉SynchronizedList ,其他類類似,可以看下源碼了解下。
測試
public class Main {
public static void main(String[] args) {
ListString names = new LinkedList();
names.add(“sub”);
names.add(“jobs”);
// 同步方法1 內部使用lock
long a = System.currentTimeMillis();
ListString strings = new CopyOnWriteArrayList(names);
for (int i = 0; i 100000; i++) {
strings.add(“param1”);
}
long b = System.currentTimeMillis();
// 同步方法2 裝飾器模式使用 synchronized
ListString synchronizedList = Collections.synchronizedList(names);
for (int i = 0; i 100000; i++) {
synchronizedList.add(“param2”);
}
long c = System.currentTimeMillis();
System.out.println(“CopyOnWriteArrayList time == “+(b-a));
System.out.println(“Collections.synchronizedList time == “+(c-b));
}
}
兩者內部使用的方法都不一樣,CopyOnWriteArrayList內部是使用lock進行加鎖解鎖完成單線程訪問,synchronizedList使用的是synchronize
進行了100000次添加後時間對比如下:
可以看出來還是使用了synchronize的集合工具類在添加方面更加快一些,其他方法這裡篇幅關係就不測試了,大家有興趣去試一下。
java中為什麼說,String是線程安全的?
String是不可變類,所以是線程安全的。
1、所有不可變類都是線程安全的,線程安全的類不一定是不可變類,如StringBuffer是可變類,靠鎖實現線程安全。
2、StringBuffer方法上都加了synchronized,StringBuilder沒有,StringBuilder在多線程情況下是會出現問題,但是線程安全線程非安全指的是你業務環境需要線程安全考慮不考慮。多並發網路編程這塊會考慮這些。
在Java語言中,線程是一種特殊的對象,它必須由Thread類或其子(孫)類來創建。
通常有兩種方法來創建線程:
其一,使用型構為Thread(Runnable)的構造子將一個實現了Runnable介面的對象包裝成一個線程。
其二,從Thread類派生出子類並重寫run方法,使用該子類創建的對象即為線程。
值得注意的是Thread類已經實現了Runnable介面,因此,任何一個線程均有它的run方法,而run方法中包含了線程所要運行的代碼。線程的活動由一組方法來控制。Java語言支持多個線程的同時執行,並提供多線程之間的同步機制(關鍵字為synchronized)。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/247113.html