信号量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());
}
}
处理完成后,记得关闭线程池!