1. 程式人生 > >執行緒安全問題(迸發)入門知識總結

執行緒安全問題(迸發)入門知識總結

關於Java解決執行緒衝突的方法簡單總結

1.在方法面前使用synchronized或者使用方法塊
2.使用各種鎖lock,Reentrantlock,讀寫鎖
3.使用volatile保證可見性
4.使用ThreadLock複製變數副本
5.java.util.concurrent的API及StringBuffer

解決執行緒安全問題的各種方法的具體實現

A.Synchronized

synchronized的具體使用方法有兩種
1.直接寫在方法的修飾符或靜態符後面
public synchronized void methodANeedSync(){//同步的程式碼}
2.在方法內使用synchronized塊
public void methodANeedSync(){
 synchronized{
   //同步的程式碼
 }
}

B.鎖

以Reentrantlock的使用為例
    在方法外例項化鎖
    
class Demo
{
Lock lock=new Reentrantlock();
void methodANeedLock(){

lock.lock()
try{//需要鎖的程式碼}
catch(Exception e){...}
finall{lock.unlock; //解鎖 }
}
}
注意不能讓鎖變成方法的區域性變數,因為每個執行緒都擁有一個區域性變數的副本,會使得獲取的鎖不一樣;

關於讀寫鎖ReadWriteLock
具體實現 ReentrantReadWriteLock
與ReentrantLock的實現基本相同只是上鎖和解鎖的時候需要註明是讀還是寫的鎖
如:
ReentrantReadWriteLock rrwl=new ReentrantReadWriteLock();
void methodANeedLock(){

rrwls.readlock.lock()
try{//需要鎖的程式碼}
catch(Exception e){...}
finall{rrwl.readlock.jianlock; //解鎖 }
}

C.volatile

此關鍵字修飾的的變量表示這個變數是易變的,不需要編譯優化,一旦發生修改即可重新整理到主記憶體中,保證變數的可見性

D.ThreadLocal

   可以理解為本地區域性變數的意思,對於儲存在裡面的變數(最好是隻有一個變數),使用ThreadLocal.get()方法訪問儲存在ThreadLocalMap的
   變數時,get()方法會判斷當前時哪個執行緒然後基於一個變數副本,就像是一個在方法外部的區域性變數一樣;
 如使用ThreadLcocal實現執行緒安全的DAO層程式碼:
 public class ThreadLocalDAO {
  private static final ThreadLocal<Connection> conLocal=new ThreadLocal<Connection>();
  public Connection getCon(){
      Connection con=conLocal.get();
      if(con==null){
          try {
              Class.forName("com.mysql.jdbc.Driver");
              try {
                  con= DriverManager.getConnection("#url","#uesr","#password");
              } catch (SQLException e) {
                  e.printStackTrace();
              }
              conLocal.set(con);
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          }

      }
      return con;
  }

}


E.各種已經封裝好且執行緒安全的集合類或其他API(多數在concurrent包內)

如常用的有:
a.實現BlockingQueue和DequeBlocking介面的所有類
{
ArrayBlockingQueue;
DelayQueue;
LinkedBlockingQueue;
PriorityBlockingQueue;
SynchronousQueue;
LinkedBlockingQueue;
}
b.所有以concurrent開頭的集合類 如:concurrentHashMap
c.StringBuffer,Vector,Stack
d.concurrent包內的其他API