Semaphore信号灯实现多个资源供多个线程竞争获取

package com.thread_test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * Created by zhen on 2017-06-06.
 * semaphore实现信号灯
 */
public class SemaphoreTest {
    /**
     * Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同事访问资源的线程个数。
     * 例如实现一个文件允许的并发访问数。
     * 线程的获取信号灯顺序可以是有序的和无序号的,在Semaphore的构造的时候可以指定是否非公平模式模式,默认为非公平模式
     */

    public static void main(String[] args){
        ExecutorService pool = Executors.newCachedThreadPool();//生成动态容量线程池
        final Semaphore semaphore = new Semaphore(3);//创建三个许可的非公平的Semaphore信号灯

        for(int i = 0; i < 10; i++){
            Runnable runnable = new Runnable() {
                public void run() {
                    try {
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程" + Thread.currentThread().getName() + " 进入 , 当前已有" + (3 - semaphore.availablePermits()) + "个并发");

                    try {
                        Thread.sleep((long)Math.random()*10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println("线程" + Thread.currentThread().getName() + "即将离开");
                    semaphore.release();
                    //这个代码有时候执行不准,因为没有和上面代码合成原子性操作
                    System.out.println("线程" + Thread.currentThread().getName() + "已经离开, 当前并发数: " + (3 - semaphore.availablePermits() ));
                }
            };
            pool.execute(runnable);
        }


    }
}

 

posted @ 2017-06-06 22:41  guodaxia  阅读(214)  评论(0)    收藏  举报