如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。
線程安全問題都是由全局變量及靜態變量引起的。
若每個線程中對全局變量、靜態變量只有讀操作,而無寫操作,一般來說,這個全局變量是線程安全的;若有多個線程同時執行寫操作,一般都需要考慮線程同步,否則就可能影響線程安全。
怎樣解決線程安全的問題那?
就需要java的鎖機制:synchronized(同步化的)線程同步:按預定的先後次序進行運行
例如:1.主鍵生成器中,每次添加一個客戶t_client的值就會增1,如果多個客戶添加,甲添加一個的同時乙也添加一個,這時可能導致數據的不對,或者未添加成功,所以就需要同步執行。
public static synchronized int generate(String tableName) {
String sql = "select value from t_table_id where table_name=? ";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int value = 0;
conn = DbUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, tableName);
rs = pstmt.executeQuery();
value = rs.getInt("value");
value++; //自加
modifyValueField(conn, tableName, value);//寫入到數據庫
return value;
}
2.多線程下,訪問數據庫,可以充分利用資源,大大縮短了訪問的時間,但是如果都要在連接數據庫的時候都創建一個連接和每個連接都要讀取配置文件,這樣就大大浪費了,系統的資源,佔用內存很大,很可能讓系統癱瘓。
讀取配置文件只需要一個實例,如果多了就會導致系統的資源浪費。
Synchronized主要有四種方式:
1. sychronized method(){}
//爲了保證銀行賬戶的安全,可以操作賬戶的方法如下:
1. public synchronized void add(int num) {
2. balance = balance + num;
3. }
4. public synchronized void withdraw(int num) {
5. balance = balance - num;
6. }
2. sychronized (objectReference) {/*block*/}
class TreadTest {
public static void main(String[] args) {
ThreadB b=new ThreadB();
b.start();
System.out.println("b is start....");
synchronized(b)
{
try {
System.out.println("Waiting for b to complete...");
b.wait();
System.out.println("Completed.Now back to main thread");
}catch (InterruptedException e){}
}
System.out.println("Total is :"+b.total);
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
System.out.println("ThreadB is running..");
for (int i=0;i<100;i++ ) {
total +=i;
System.out.println("total is "+total);
}
notify();
}
}
} 全局變量
3. static synchronized method(){}
//上面主鍵生成器就是public static synchronized int generate(String tableName) {}
4. sychronized(classname.class)
注意:其中1 和2是代表鎖當前對象,即一個對象就一個鎖,3和4代表鎖這個類,即這個類的鎖