信號量Semaphore是一個併發工具類,用來控制可同時併發的線程數,其內部維護了一組虛擬許可,通過構造器指定許可的數量,每次線程執行操作時先通過acquire方法獲得許可,執行完畢再通過release方法釋放許可。如果無可用許可,那麼acquire方法將一直阻塞,直到其它線程釋放許可。
比如說我們現在要處理一批訂單,(如下單,取消,或者對賬),訂單量比較多,才用多線程處理
先創建一個簡單訂單model示例
package test;
import java.io.Serializable;
/**
* @Description
* @Author penn
* @Date 2019-08-28
*/
public class Order implements Serializable {
private static final long serialVersionUID = 7592930394427200495L;
private String orderId;
private String orderName;
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
}
然後我們通過線程池去處理,最多10個線程,意思是同一時刻,最多10個線程在處理訂單業務
package test;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* @Description
* @Author penn
* @Date 2019-08-28
*/
public class Gtest {
private static SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
public static void main(String args[]){
try{
ExecutorService executorService = Executors.newFixedThreadPool(10);
final Semaphore semaphore = new Semaphore(10);
List<Order> persons = initData();
for(Order p : persons){
executorService.execute(() -> {
try {
semaphore.acquire();
System.out.println(p.getOrderId() + "," + p.getOrderName() + getFormatTimeStr());
//業務代碼開始
//業務代碼
//業務代碼結束
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
}catch (Exception e){
System.out.println(e.getMessage());
}
}
private static List<Order> initData(){
List<Order> persons = new ArrayList<>();
for(int i =0;i<100;i++){
Order person = new Order();
person.setOrderId("ID_" + (1000+i));
person.setOrderName("NAME" + (1000+i));
persons.add(person);
}
return persons;
}
public static String getFormatTimeStr() {
return sf.format(new Date());
}
}
處理完成後,記得關閉線程池!