如何解決執行緒安全問題
阿新 • • 發佈:2019-02-01
有2種解決方法。 第一,是採用原子變數,畢竟執行緒安全問題最根本上是由於全域性變數和靜態變數引起的,只要保證了對於變數的寫操作要麼全寫要麼不寫,就可以解決執行緒安全,定義變數用sig_atomic_t和volatile。 第二,就是實現執行緒間同步啦,用互斥索,訊號量。讓執行緒有序的訪問變數就可以啦
在編寫一個類時,如果該類中的程式碼可能運行於多執行緒環境下,那麼就要考慮同步的問題,Java實現執行緒同步的方法很多,具體如下。 (1)synchronized關鍵字 在Java中內建了語言級的同步原語synchronized關鍵字,其在多執行緒條件下實現了對共享資源的同步訪問。根據synchronized關鍵字修飾的物件不同可以分為以下幾種情況。 *synchronized關鍵字同步方法 public synchronized void method(){ //do something } 注意:如果使用synchronized關鍵字同步方法,很容易誤認為同步關鍵字鎖住了它所包圍的程式碼。但是實際情況卻不是這樣,同步加鎖的是物件而並非程式碼。因此。如果在一個類中有一個同步方法,該方法是可以被兩個不同的執行緒同時執行的,只要每個執行緒自己建立一個該類的例項即可。 示例程式碼: package newthread; public class TestSync { public static void main(String[] args) { MyThread1 my1=new MyThread1(1); MyThread1 my2=new MyThread1(3); my1.start(); my2.start(); } } class MyThread1 extends Thread{ private int val; public MyThread1(int v){ val=v; } public synchronized void printVal(int v){ for(int i=0;i<100;i++){ System.out.print(v); } } public void run(){ printVal(val); } } 執行程式碼結果是1和3交叉輸出的,即1和3兩個執行緒在併發執行printVal方法,並沒有實現同步功能。原因在於synchronized關鍵字鎖定的是物件而並非程式碼塊,如果需要實現真正的同步,必須同步一個全域性物件或者對類進行同步。synchronized關鍵字同步類的格式如下: synchronized(MyThread.class){} 改進程式碼 package newthread; public class TestSync_2 { public static void main(String[] args) { MyThread_2 my1=new MyThread_2(1); my1.start(); MyThread_2 my2=new MyThread_2(2); my2.start(); } } class MyThread_2 extends Thread{ private int val; public MyThread_2(int v){ val=v; } public void printVal(int v){ synchronized(MyThread_2.class){ for(int i=0;i<100;i++){ System.out.print(v);