【并发编程】-Semaphore的同步

66 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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个线程是同步的。