一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
Semaphore的同步性
多线程中的同步概念就是排着队去执行一个任务,执行任务是一个一个执行,并不能并行执行,这样的优点是有助于程序逻辑的正确性,不会出现非线程安全问题,保证软件 系统功能上的运行稳定性。
使用Semaphore类实现限制线程并发数
@Slf4j
public class SemaphoreService {
private Semaphore semaphore = new Semaphore(1);
public void testSemaphore(){
semaphore.acquire();
log.info("线程名:{}-开始执行时间:{}",Thread.currentThread().getName(),System.currentTimeMillis());
Thread.sleep(5000);
log.info("线程名:{}-结束执行时间:{}",Thread.currentThread().getName(),System.currentTimeMillis());
semaphore.release();
}
}
类SemaphoreService的构造函数参数permits是许可数量,代表同一时间内,最多允许多少个线程同时执行acquire()和release()之间的代码。
无参方法acquire()的作用是使用1个许可,是减法操作。
创建3个线程类调用testSemaphore()方法如下:
public class ThreadA extends Thread {
private SemaphoreService service;
public ThreadA(SemaphoreService service){
super();
this.service=service;
}
@Override
public void run(){
service.testSemaphore();
}
}
public class ThreadB extends Thread {
private SemaphoreService service;
public ThreadB(SemaphoreService service){
super();
this.service=service;
}
@Override
public void run(){
service.testSemaphore();
}
}
public class ThreadC extends Thread {
private SemaphoreService service;
public ThreadC(SemaphoreService service){
super();
this.service=service;
}
@Override
public void run(){
service.testSemaphore();
}
}
运行类代码如下:
public class TestSemaphore {
public static void main(String[] args) {
SemaphoreService service = new SemaphoreService();
ThreadA threadA = new ThreadA(service);
threadA.setName("A");
ThreadB threadB = new ThreadB(service);
threadB.setName("B");
ThreadC threadC = new ThreadC(service);
threadC.setName("C");
threadA.start();
threadB.start();
threadC.start();
}
}
程序运行后的结果如下:
14:58:37.306 [B] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名:B-开始执行时间:1648882717283
14:58:38.758 [B] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名:B-结束执行时间:1648882718758
14:58:38.759 [A] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名:A-开始执行时间:1648882718759
14:58:40.052 [A] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名:A-结束执行时间:1648882720052
14:58:40.052 [C] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名:C-开始执行时间:1648882720052
14:58:41.136 [C] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名:C-结束执行时间:1648882721136
使用new Semaphore(1)来定义最多允许1个线程执行acquire()和release()之间的代码,所以打印出的结果是3个线程是同步的。