一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
Semaphore的公平与非公平信号量
公平信号量是获取锁的顺序与线程启动的顺序有关,但不代表100%地获得信号量。
@Slf4j
public class SemaphoreService {
private boolean isFair = false;
private Semaphore semaphore = new Semaphore(1,isFair);
public void testSemaphore(){
try {
semaphore.acquire();
Thread.sleep(5000);
log.info("线程名{}获取许可",Thread.currentThread().getName());
} catch (InterruptedException e) {
log.error("线程名:{} 进入了catch",Thread.currentThread().getName());
e.printStackTrace();
}finally {
semaphore.release();
}
}
}
运行类代码如下:
public class TestSemaphore {
public static void main(String[] args) {
SemaphoreService service = new SemaphoreService();
ThreadA[] threadAS = new ThreadA[5];
for (int i = 0; i < 5 ; i++) {
threadAS[i] = new ThreadA(service);
threadAS[i].start();
}
}
}
程序结果如下:
15:11:21.344 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.entity.ThreadA - 线程名 Thread-1 启动
15:11:21.344 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.entity.ThreadA - 线程名 Thread-2 启动
15:11:21.344 [Thread-3] INFO com.ozx.concurrentprogram.semaphore.entity.ThreadA - 线程名 Thread-3 启动
15:11:21.345 [Thread-4] INFO com.ozx.concurrentprogram.semaphore.entity.ThreadA - 线程名 Thread-4 启动
15:11:21.345 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.entity.ThreadA - 线程名 Thread-0 启动
15:11:26.353 [Thread-3] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名Thread-3获取许可
15:11:31.353 [Thread-2] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名Thread-2获取许可
15:11:36.353 [Thread-1] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名Thread-1获取许可
15:11:41.353 [Thread-4] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名Thread-4获取许可
15:11:46.354 [Thread-0] INFO com.ozx.concurrentprogram.semaphore.service.SemaphoreService - 线程名Thread-0获取许可
线程先启动,但是不一定先能获取许可,所以需要将Semaphore的公平锁置为true,公平信号量运行的效果是线程启动的顺序与调用Semaphore.acquire()的顺序有关,也就是先启动的线程优先获得许可。
方法tryAcquire()的使用
无参方法tryAcquire()的作用是尝试地获得1个许可,如果获取不到则返回false。此方法通常与if语句结合使用,其具有无阻塞的特点。无阻塞的特点可使线程不至于在同步点一直持续等待的状态,如果if语句判断不成立则线程会继续走else语句,程序会继续向下运行。