java語言的線程安全級別


java是支持多線程編程的語言,java中提供了很多類,如果把這些類的實現按照線程安全級別來排序的話,則由強到弱主要可以分為以下幾個級別

1 絕對線程安全

在任何環境下,調用者都不需要考慮額外的同步措施,都能夠保證程序的正確性。

這個定義要求很嚴格,java里面滿足這個要求的類比較少,對於實現jsr133規范(java內存模型)的jdk(一般指jdk5.0之上),一般的不變類都是滿足絕地線程安全的。比如 String,Integer類。一般情況下,定義了如果一個類里面所有字段都是final類型的,一般都認為這個類是不變的。不變類都是絕對線程安全的。

但是下面這個類的定義,就不是絕對安全的。雖然沒有辦法修改Money類的屬性值(反射機制例外),但是在構造構造Money的時候,可能發生並發問題.這個可以參考Java內存模型-jsr133規范介紹里面的例子。

public class Money {

	private int yuan;
	private int fen;

	public Money(int yuan, int fen) {
		this.yuan = yuan;
		this.fen = fen;
	}

	public String formatString() {
		return "" + yuan + "." + fen;
	}
}

2 相對線程安全

在一般情況下,調用者都不需要考慮線程同步,大多數情況下,都能夠正常運行。jdk里面大多數類都是相對安全的。最常見的例子是java里面Vector類。記得網上經典的面試問題就是Vertor 和 List的區別,一般情況下都會說Vertor是線程安全的,List是非線程安全的。但是考慮以下情況,一個線程遍歷Vector,另外一個線程刪除Vector中的一個元素,會導致什么問題?有可能在read方法中拋出ArrayIndexOutOfBoundException

import java.util.Vector;

public class VectorTest {

	private static Vector v = new Vector();

	public static void read() {
		int size = v.size();
		for (int i = 0; i < size; i++) {
			v.get(i);
		}
	}

	public static void delete() {
		if (v.iterator().hasNext()) {
			v.remove(0);
		}
	}
}

3 非線程安全

在多線程環境下,調用者需要考慮同步問題。如果調用者通過額外的同步機制,可以保證線程的安全性。

jdk中,List,Map,DateFormat等對象都是非線程安全的。所以在使用這些對象的時候,都要考慮是否會發生線程安全問題。

4 線程對立

在多線程環境中,無論采用什么樣的機制,都無法解決線程安全問題。這種還是極為少見的。比如java.lang.Thread類,提供了suspend,stop,resume方法。

suspend 和 resume 方法可能導致兩個線程死鎖。

例如 線程A,先鎖住關鍵資源S,然后被線程B suspend,由於資源被A鎖住,除非線程A被resume,否則其他線程無法訪問S,如果遇到S,則阻塞。 而線程B suspend線程A之后,需要申請關鍵資源S,獲取到S之后,在resume A。此時線程A 和 線程B就由可能導致死鎖。

對於stop方法,由於調用stop方法的時候,被stop的線程回釋放所有他獲得的所有monitor,被monitor保護的資源可能存在一致性問題。其他線程可能看到的對象就可能不一致。

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM