當前位置:編程學習大全網 - 源碼下載 - springboot之幾種同步,線程安全處理的方法

springboot之幾種同步,線程安全處理的方法

在壹些公***資源的處理上,經常會出現對公***資源的爭奪使用權限的問題,以及對數據庫處理時,容易出現線程安全的問題,比如對數據操作時的壹致性,可見性等等。?

這時候,為了避免這樣的問題,壹般的處理方式是當某壹個公***資源在被某壹個線程調用時,把這個公***資源(即代碼塊)鎖住。?

下面先大概介紹兩種簡單的同步方法:?

註:同步是壹種高開銷的操作,因此應該盡量減少同步的內容。?

沒有必要同步整個方法,只使用synchronized代碼塊同步關鍵代碼即可。?

1.同步方法?

即有synchronized關鍵字修飾的方法。?

由於java的每個對象都有壹個內置鎖,當用此關鍵字修飾方法時,?

內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處於阻塞狀態。?

代碼如:?

public synchronized void demo(){}?

註: synchronized關鍵字也可以修飾靜態方法,此時如果調用該靜態方法,將會鎖住整個類?

2.同步代碼塊?

即有synchronized關鍵字修飾的語句塊。?

被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步?

代碼如:?

synchronized(object){?

}?

lock.lock(); try {

System.out.println("已鎖住"); for (int i=0;i<10;i++) { ? //放大代碼塊執行完成的時間,便於觀察

System.out.println(i); try {

System.out.println(Thread.currentThread().getName()+ "休眠5秒!");

Thread.sleep(5000);//放大代碼塊執行完成的時間,便於觀察

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}finally { lock.unlock();

System.out.println("解鎖");

}12345678910111213141516

當代碼塊被鎖住後,有其它的線程來調用被鎖住的線程時,必須先等待上壹個線程使用完之後,釋放資源,才能繼續執行。?

以上兩種方法很簡單,就不過多的寫了,但是這兩種方法在使用時,有以下幾個問題:?

(1). 當公***資源被占用時,其它線程必須等待資源被釋放後才能執行,這種場景適用於對數據庫的操作,保證其數據的原子性。當被搶占的資源是即時的公***資源,只有在某壹時刻搶到才有意義,比如說在公***場所對空調的控制,大家都要爭奪對空調的控制權,但如果是用上述的方法,對空調的控制會按照發出請求的時間,依次執行,那就沒有意義了。所以這種場景適合只執行最先搶到資源的線程,在資源被占用時,殺死其它的請求線程。這種情況用以下的方法實現?

3. Semaphore並發包?

Semaphore是基於計數的信號量,它可以設定壹個資源的總數量,基於這個總數量,多線程競爭獲取許可信號,做自己的申請後歸還,超過總數量後,線程申請許可,信號將會被阻塞。等到有資源時,繼續執行。?

下面在springboot中實現:

@Contorller public class Controller(){

Semaphore semaphore=new Semaphore(1); ?//定義資源的總數量

@GetMapping("/userInfo/request")

@ResponseBody public String Resquest(){ int availablePermits=semaphore.availablePermits();//可用資源數

if(availablePermits>0){

System.out.println("搶到資源");

}else{

System.out.println("資源已被占用,稍後再試"); return "Resource is busy!";

} try {

semaphore.acquire(1); ?//請求占用壹個資源

System.out.println("資源正在被使用");

Thread.sleep(30000);//放大資源占用時間,便於觀察

} catch (InterruptedException e) {

e.printStackTrace();

}finally{

semaphore.release(1);//釋放壹個資源

} return "Success";

}

}123456789101112131415161718192021222324252627

當只有壹個資源請求時,效果如下:?

程序運行完之後,頁面會返回Success?

當有多個線程同時請求資源時,效果如下:?

先獲得資源的線程會在30秒之後顯示success,後面請求的線程會直接返回?

大致的思路和框架就是這樣,可根據自己的需要進行修改。

  • 上一篇:這個動畫片叫什麽名字?
  • 下一篇:供銷合作社的總體目的是什麽?
  • copyright 2024編程學習大全網