控制线程数量之-Semaphore

使用Semaphore的简单例子了解一下Semaphore使用
 
//这里可能是在一个项目中唯一使用的一个newCachedThreadPool,别的都是new一个fixed的大小
    public static ExecutorService exec = Executors.newCachedThreadPool();
    private static List<String> userList;

    static {
        userList=new ArrayList<String>();
        for (int i = 0; i < 100; i++){
            userList.add(String.valueOf(i));
        }
    }


    /**
     * 使用信号量控制线程数量
     */
    public static void simpleSemaphore() {
        //构建最大的线程并发
        final Semaphore sem = new Semaphore(10);

        final Semaphore sycSem = new Semaphore(5, true);//这里使用非竞争锁
        //模拟100个客户访问
        for (final String user:userList) {
            Runnable run = new Runnable() {
                public void run() {
                    try {
                        sem.acquire();//获得允许
                        System.out.println(user + "用户进入----");
                        sem.release();//释放访问
                        System.out.println("访问后还有" + sem.availablePermits() + "个线程空间可以使用");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            exec.execute(run);
        }
        exec.shutdown();
    }

执行结果
0用户进入----
访问后还有10个线程空间可以使用
1用户进入----
访问后还有9个线程空间可以使用
16用户进入----
访问后还有9个线程空间可以使用
6用户进入----
访问后还有9个线程空间可以使用
19用户进入----
访问后还有9个线程空间可以使用
23用户进入----
访问后还有9个线程空间可以使用
26用户进入----


如果把上边的用户换成一个个线程池该怎么处理
 //这里可能是在一个项目中唯一使用的一个newCachedThreadPool,别的都是new一个fixed的大小
    public static ExecutorService exec = Executors.newCachedThreadPool();

    private static BlockingQueue<TaskPool> taskPools = new ArrayBlockingQueue<TaskPool>(1000);


    private String user;

    public static void addPoolTask(TaskPool user) {
        if (taskPools.size() < 1000) {//建议添加初始化值
            taskPools.add(user);
        } else {
            //转移或者是做别的处理
        }
    }

    /**
     * 使用信号量控制线程数量
     */
    public static void simpleSemaphore() {
        //构建最大的线程并发
        final Semaphore sem = new Semaphore(10);

        final Semaphore sycSem = new Semaphore(5, true);//这里使用非竞争锁
        //模拟100个客户访问
        while (taskPools.size() > 0) {
            try {
                final TaskPool taskPool = taskPools.take();
                Runnable run = new Runnable() {
                    public void run() {
                        try {
                            sem.acquire();//获得允许
                            //这里执行对应的task池事情
                            taskPool.excute();

                            sem.release();//释放访问
                            System.out.println("线程池" + taskPool.toString() + "访问后还有" + sem.availablePermits() + "个线程空间可以使用");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                exec.execute(run);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        exec.shutdown();
    }

基于用户扩展的多线程池管理

public interface TaskPool {

    void excute();
}
public class MyFirstPoolTask implements TaskPool {

    public ExecutorService exec = Executors.newFixedThreadPool(1);
    private int init;
    private int max = 10;

    public MyFirstPoolTask(int init) {
        if (max < init)
            System.out.println("数值过大");
        this.exec = Executors.newFixedThreadPool(init);
    }


    public void excute() {
        for (int i = 0; i < 5; i++) {
            final int z = i;
            Runnable rn = new Runnable() {
                public void run() {
                    System.out.println("MyFirstPoolTask进行我的业务处理"+Thread.currentThread().getName());
                }
            };
            exec.execute(rn);
        }
        exec.shutdown();
    }
}

public class MySecondPoolTask implements TaskPool {

    public ExecutorService exec = Executors.newFixedThreadPool(1);
    private int init;
    private int max = 10;

    public MySecondPoolTask(int init) {
        if (max < init)
            System.out.println("数值过大");
        this.exec = Executors.newFixedThreadPool(init);
    }


    public void excute() {
        for (int i = 0; i < 5; i++) {
            final int z = i;
            Runnable rn = new Runnable() {
                public void run() {
                    System.out.println("MySecondPoolTask进行我的业务处理"+Thread.currentThread().getName());
                }
            };
            exec.execute(rn);
        }
        exec.shutdown();
    }
}


执行后的结果
线程池test.com.jd.hotel.janleTest.MyFirstPoolTask@2678a212访问后还有9个线程空间可以使用
MyFirstPoolTask进行我的业务处理pool-3-thread-3
MyFirstPoolTask进行我的业务处理pool-3-thread-3
MyFirstPoolTask进行我的业务处理pool-3-thread-3
线程池test.com.jd.hotel.janleTest.MySecondPoolTask@151a64ed访问后还有10个线程空间可以使用
MySecondPoolTask进行我的业务处理pool-5-thread-1
MySecondPoolTask进行我的业务处理pool-5-thread-1
MyFirstPoolTask进行我的业务处理pool-3-thread-1
MySecondPoolTask进行我的业务处理pool-5-thread-4
MySecondPoolTask进行我的业务处理pool-5-thread-2
MyFirstPoolTask进行我的业务处理pool-3-thread-2
MySecondPoolTask进行我的业务处理pool-5-thread-3

猜你喜欢

转载自janle.iteye.com/blog/2344370