Samaphore

一 Samaphore的概念和工作流程

1 概念

信号量;它允许线程集等待,直到被允许继续运行为止,一个信号量管理多个许可,线程必须请求许可,否则等待。

特点:控制访问多个共享资源的计数器。

使用场景:通常用于限制访问资源的线程总数,流量控制。

基本操作:acquire(); 获取一个许可

                  release(); 释放一个许可

二 基本使用

使用场景:一个停车场可以停放10两小汽车或者5辆大卡车(一辆大卡车占用2个小汽车的停车位),现有14辆小汽车,8辆大卡车要进入停车场。

示例代码

package com.bxp.threadtest.samaphoretest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreTest {
    static Logger logger = LoggerFactory.getLogger(SemaphoreTest.class);
    /**
     * 默认使用非公平锁
     */
    private static Semaphore semaphore = new Semaphore(10);

    public static void main(String[] args) {
        Car car = new Car();
        Truck truck = new Truck();
        for (int i = 0; i < 14; i++) {
            new Thread(car).start();
        }
        for (int i = 0; i < 8; i++) {
            new Thread(truck).start();
        }
    }

    public static class Car implements Runnable{

        @Override
        public void run() {
            try {
                semaphore.acquire();
                logger.info("小汽车" + Thread.currentThread().getName() + "进入停车场");
                Random random = new Random();
                int time = random.nextInt(20);
                TimeUnit.SECONDS.sleep(time);
                logger.error("小汽车" + Thread.currentThread().getName() + "停留" + time + "秒");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                semaphore.release();
            }
        }
    }

    public static class Truck implements Runnable{

        @Override
        public void run() {
            try {
                semaphore.acquire(2);
                logger.info("大卡车" + Thread.currentThread().getName() + "进入停车场");
                Random random = new Random();
                int time = random.nextInt(20);
                TimeUnit.SECONDS.sleep(time);
                logger.error("大卡车" + Thread.currentThread().getName() + "停留" + time + "秒");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                semaphore.release(2);
            }
        }
    }
}

 运行结果:


23:12:31.295 [Thread-3] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-3进入停车场
23:12:31.295 [Thread-4] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-4进入停车场
23:12:31.295 [Thread-9] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-9进入停车场
23:12:31.295 [Thread-6] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-6进入停车场
23:12:31.296 [Thread-11] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-11进入停车场
23:12:31.296 [Thread-1] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-1进入停车场
23:12:31.295 [Thread-2] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-2进入停车场
23:12:31.295 [Thread-0] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-0进入停车场
23:12:31.296 [Thread-5] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-5进入停车场
23:12:31.295 [Thread-8] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-8进入停车场
23:12:31.322 [Thread-2] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-2停留0秒
23:12:31.322 [Thread-4] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-4停留0秒
23:12:31.322 [Thread-7] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-7进入停车场
23:12:31.322 [Thread-10] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-10进入停车场
23:12:32.327 [Thread-7] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-7停留1秒
23:12:33.308 [Thread-11] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-11停留2秒
23:12:33.310 [Thread-18] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-18进入停车场
23:12:34.307 [Thread-1] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-1停留3秒
23:12:40.310 [Thread-6] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-6停留9秒
23:12:40.310 [Thread-0] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-0停留9秒
23:12:40.311 [Thread-17] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-17进入停车场
23:12:41.315 [Thread-8] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-8停留10秒
23:12:41.316 [Thread-16] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-16进入停车场
23:12:42.301 [Thread-3] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-3停留11秒
23:12:42.301 [Thread-13] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-13进入停车场
23:12:44.310 [Thread-9] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-9停留13秒
23:12:44.310 [Thread-12] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-12进入停车场
23:12:44.325 [Thread-10] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-10停留13秒
23:12:45.315 [Thread-12] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-12停留1秒
23:12:45.315 [Thread-14] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-14进入停车场
23:12:47.314 [Thread-13] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-13停留5秒
23:12:49.313 [Thread-18] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-18停留16秒
23:12:49.314 [Thread-19] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-19进入停车场
23:12:50.304 [Thread-5] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 小汽车Thread-5停留19秒
23:12:50.304 [Thread-15] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-15进入停车场
23:12:52.306 [Thread-15] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-15停留2秒
23:12:52.306 [Thread-20] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-20进入停车场
23:12:52.322 [Thread-19] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-19停留3秒
23:12:52.322 [Thread-16] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-16停留11秒
23:12:52.322 [Thread-21] INFO com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-21进入停车场
23:12:53.319 [Thread-17] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-17停留13秒
23:12:57.327 [Thread-14] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-14停留12秒
23:13:04.332 [Thread-21] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-21停留12秒
23:13:11.314 [Thread-20] ERROR com.bxp.threadtest.samaphoretest.SemaphoreTest - 大卡车Thread-20停留19秒

三 注意事项

1 注意事项

(1)Samaphore默认使用的是非公平锁,可以在创建时指定使用公平锁。

(2)线程可以申请多个许可,也可以释放多个许可。

          acquire(n); 获取n个许可

          release(n); 释放n个许可

(3)许可数量初始化为1时,可以当做普通的互斥锁来使用。

(4)获取许可和释放许可的是线程,不是semaphore对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值