java并发之同步工具类二之信号灯semaphore

java中信号灯可以控制多个线程同时访问同一个资源的操作数量,注意这句话的重点在于“控制”二字。即可以为某种容器施加边界限制,也可以实现对某种资源的池化,比如线程池中限制最大运行5个线程,当有有超过5个线程同时来访问线程池的时候,必定有一个线程会处于阻塞等待状态。通过控制边界数量,可以避免过度线程占用内存而引发内存不足问题。其实现是通过一组运行在有界容器内的访问许可permit
比如商场的车库,车位有限,但是要在这里停车的数量大于车位,就必须有部分车辆要等待车库里面的车先开出来,在此期间将一直处于阻塞。且看下面代码。

import java.util.concurrent.Semaphore;

/**
 *
 * @author Jerry
 * @date 2017/12/24 0024
 */
public class Garage {

    public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(3);//停车场只允许停3辆车
        System.out.println("车库未停任何车辆......");
        for (int i=1;i<=5;i++){
            Thread thread=new Thread(new Car("粤A"+i,semaphore));
            thread.start();
        }
    }
    static class Car implements Runnable{
        private String name;
        private Semaphore semaphore;

        public Car(String name, Semaphore semaphore) {
            this.name = name;
            this.semaphore = semaphore;
        }

        @Override
        public void run() {
            try {
                semaphore.acquire();//进入车库,获取入库证
                System.out.println("+ "+name+"开进车库");
                parking();
                semaphore.release();//退出车库,退还入库证
                System.out.println("- "+name+"已经离开车库");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void parking() {
            System.out.println(name+"停车中");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

运行结果如下,程序中限制了车位为3,但是停车数量为5,意味着总有两部车要等待前面的车辆空出车位才能入库。

车库未停任何车辆......
+ 粤A1开进车库
粤A1停车中
+ 粤A2开进车库
粤A2停车中
+ 粤A3开进车库
粤A3停车中
- 粤A1已经离开车库
+ 粤A4开进车库
+ 粤A5开进车库
- 粤A2已经离开车库
粤A5停车中
粤A4停车中
- 粤A3已经离开车库
- 粤A5已经离开车库
- 粤A4已经离开车库

你可能感兴趣的:(高并发)