美文网首页我爱编程
Semaphore信号量

Semaphore信号量

作者: heen11 | 来源:发表于2018-12-11 21:40 被阅读65次

    Semaphore:控制并发访问的个数。

    Semaphore就像是去餐厅吃饭的问题,例如:去餐厅吃饭正好是下课时间人比较多,而且有20个都想要去买饼吃,而且一起到,但是只有3个餐厅窗口是卖饼的。这个时候我们就需要去排队。而Semaphore可以解决排队这个问题,只有当前面的人卖完之后,我们才可以释放一个窗口让其它同学来买饼。由以下代码可以看出semaphore.acquire()来进行排队,当卖完饼走人时,这个时候可以释放一个窗口semaphore.release()让其它同来买饼semaphore.acquire(),而买饼窗口的的数量取决于new Semaphore(X)的大小。

package com.jiaoshou.concurency.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Semaphore;

/**

* @author yangkaifei

* @date 2018/12/11 13:38

*/

@Slf4j

public class SemaphoreExample {

        //线程数(买饼人数)

        private static int threadCount=20;

        public static void main(String[] args)throws InterruptedException {

            //线程池

            ExecutorService exec=Executors.newCachedThreadPool();

            //允许并发数(窗口数)

            final Semaphore semaphore=new Semaphore(3);

            for (int i =0; i < threadCount; i++) {

                final int threadNum=i;

                exec.execute(

                    ()->{

                        try {

                            semaphore.acquire();//拿到一个许可(买饼占用一个窗口)

                            test(threadNum);//要做并发控制的代码(买饼操作)

                            semaphore.release();//释放一个许可(卖完并离开,释放一个窗口)

                        }catch (Exception e) {

                            e.printStackTrace();

                            log.info("出现异常");

                        }

                });

            }

            exec.shutdown();//关闭线程池

        }

        private static void test(int number)throws Exception {

            log.info("{}",number);

            Thread.sleep(1000);

        }

}

    在现实生活中还可以会遇见这样的情况,

    1、例如一个恶霸,他也喜欢吃饼,但是这个人非常霸道非要一个人占用3个窗口,这个时候用代码可以这样去实现semaphore.acquire(3),3代表的是这个恶霸一次排队要霸占3个窗口。

    2、可能买饼的同学还会遇到这样的情况,刚下课就去买饼,同样还是20个人一起到,这20个人都没有耐心。如果他们尝试这占不到窗口就不买饼,遇到这种情况我么只需要将try里面的代码改为。如果这样的情况下,很明显只有3位同学(开放的窗口数量)能买到饼

if(semaphore.tryAcquire()){//尝试获取一个许可(尝试排队)

    test(threadNum);//要做并发控制的代码(买饼)

    semaphore.release();//释放X个许可(离开)

}

    3、还是例2的情况,但是现在同学们变的有耐心了,同学们都可以接受等5秒,如果5秒内还没有占到买饼窗口就离开不买饼吃了。这个时候只需将tryAcquire加个参数就可以

if(semaphore.tryAcquire(5000,TimeUnit.MILLISECONDS)){//尝试获取一个许可,5秒内

相关文章

网友评论

    本文标题:Semaphore信号量

    本文链接:https://www.haomeiwen.com/subject/oaqyhqtx.html