J.U.C系列(三)Semaphore的使用

导读:本篇文章讲解 J.U.C系列(三)Semaphore的使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Semaphore类似于操作系统中的信号量,可以控制值对互斥资源的访问线程数。
举个例子:比如一共3把伞,9个人来借伞,伞借出去了就不能借给其他人,直到有人还伞。参考以下小demo理解以下。

package com.leo.demo.juctest;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;

/**
 * @ClassName: SemaphoreExample
 * @Description: 关于Semaphore测试的小demo
 * @Author: leo825
 * @Date: 2020-05-10 15:35
 * @Version: 1.0
 */
public class SemaphoreExample {

    public static void main(String[] args) {
        //假如有3把雨伞
        final int umbrella = 3;
        //假如有10个人借伞
        final int persons = 9;
        //设置信号量
        Semaphore semaphore = new Semaphore(umbrella);
        //定义一个线程池模拟借伞
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < persons; i++) {
            executorService.execute(() -> {
                try {
                    //借伞
                    semaphore.acquire();
                    getThreadLog("借伞成功,当前可接伞剩余:" + semaphore.availablePermits() + " 把");
                    //模拟借用时长
                    int times = ThreadLocalRandom.current().nextInt(10);
                    getThreadLog("借用时长为:" + times + " 天");
                    TimeUnit.MILLISECONDS.sleep(times);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                    getThreadLog("还伞成功,当前可接伞剩余:" + semaphore.availablePermits() + " 把");
                }
            });
        }
        executorService.shutdown();
    }

    /**
     * 获取线程名和时间
     *
     * @return
     */
    public static void getThreadLog(String logContent) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("[");
        stringBuffer.append(Thread.currentThread().getName());
        stringBuffer.append(" ");
        stringBuffer.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
        stringBuffer.append("]");
        stringBuffer.append(logContent);
        System.out.println(stringBuffer.toString());
    }
}

打印结果如下:

[pool-1-thread-3 2020-05-10 16:14:31.563]借伞成功,当前可接伞剩余:0[pool-1-thread-2 2020-05-10 16:14:31.564]借伞成功,当前可接伞剩余:1[pool-1-thread-1 2020-05-10 16:14:31.563]借伞成功,当前可接伞剩余:2[pool-1-thread-2 2020-05-10 16:14:31.566]借用时长为:1[pool-1-thread-3 2020-05-10 16:14:31.566]借用时长为:4[pool-1-thread-1 2020-05-10 16:14:31.566]借用时长为:6[pool-1-thread-4 2020-05-10 16:14:31.567]借伞成功,当前可接伞剩余:0[pool-1-thread-2 2020-05-10 16:14:31.567]还伞成功,当前可接伞剩余:1[pool-1-thread-4 2020-05-10 16:14:31.567]借用时长为:9[pool-1-thread-5 2020-05-10 16:14:31.570]借伞成功,当前可接伞剩余:0[pool-1-thread-3 2020-05-10 16:14:31.570]还伞成功,当前可接伞剩余:1[pool-1-thread-5 2020-05-10 16:14:31.570]借用时长为:0[pool-1-thread-5 2020-05-10 16:14:31.571]还伞成功,当前可接伞剩余:1[pool-1-thread-6 2020-05-10 16:14:31.571]借伞成功,当前可接伞剩余:0[pool-1-thread-6 2020-05-10 16:14:31.571]借用时长为:0[pool-1-thread-6 2020-05-10 16:14:31.572]还伞成功,当前可接伞剩余:1[pool-1-thread-7 2020-05-10 16:14:31.572]借伞成功,当前可接伞剩余:0[pool-1-thread-1 2020-05-10 16:14:31.572]还伞成功,当前可接伞剩余:1[pool-1-thread-8 2020-05-10 16:14:31.572]借伞成功,当前可接伞剩余:0[pool-1-thread-7 2020-05-10 16:14:31.572]借用时长为:8[pool-1-thread-8 2020-05-10 16:14:31.573]借用时长为:8[pool-1-thread-4 2020-05-10 16:14:31.576]还伞成功,当前可接伞剩余:1[pool-1-thread-9 2020-05-10 16:14:31.576]借伞成功,当前可接伞剩余:0[pool-1-thread-9 2020-05-10 16:14:31.577]借用时长为:9[pool-1-thread-8 2020-05-10 16:14:31.581]还伞成功,当前可接伞剩余:2[pool-1-thread-7 2020-05-10 16:14:31.581]还伞成功,当前可接伞剩余:2[pool-1-thread-9 2020-05-10 16:14:31.587]还伞成功,当前可接伞剩余:3

可以从日志中看出,当有伞的时候才可以借,也就是说谁还了伞,下一个人才可以借用,这就是信号量,主要控制互斥资源的访问。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72712.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!