首页 > 技术文章 > 如何控制某个方法允许并发访问线程的个数

scar1et 2019-11-20 20:04 原文

import java.util.concurrent.Semaphore;

/**
 * 如何控制某个方法允许并发访问线程的个数
 * permits the initial number of permits available. This value may be negative,
 * in which case releases must occur before any acquires will be granted.
 * fair true if this semaphore will guarantee first-in first-out granting of
 * permits under contention, else false
 */
public class SemaphoreTest {
    static Semaphore semaphore = new Semaphore(5, true);

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test();
                }
            }).start();
        }
    }

    public static void test() {
        try {
            //申请一个新的请求
            semaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"进来了");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"走了");
        //释放一个请求
        semaphore.release();
    }
}

运行结果如下:

  

Thread-0进来了
Thread-1进来了
Thread-4进来了
Thread-2进来了
Thread-3进来了
Thread-0走了
Thread-1走了
Thread-6进来了
Thread-4走了
Thread-5进来了
Thread-9进来了
Thread-2走了
Thread-8进来了
Thread-3走了
Thread-7进来了
Thread-5走了
Thread-6走了
Thread-9走了
Thread-8走了
Thread-10进来了
Thread-11进来了
Thread-12进来了
Thread-13进来了
Thread-7走了
Thread-14进来了
Thread-11走了
Thread-13走了
Thread-15进来了
Thread-12走了
Thread-17进来了
Thread-10走了
Thread-16进来了
Thread-18进来了
Thread-14走了
Thread-19进来了
Thread-15走了
Thread-16走了
Thread-20进来了
Thread-17走了
Thread-18走了
Thread-22进来了
Thread-21进来了
Thread-23进来了
Thread-19走了
Thread-24进来了
Thread-23走了
Thread-21走了
Thread-25进来了
Thread-22走了
Thread-20走了
Thread-27进来了
Thread-26进来了
Thread-28进来了
Thread-24走了
Thread-29进来了
Thread-25走了
Thread-27走了
Thread-26走了
Thread-28走了
Thread-32进来了
Thread-31进来了
Thread-30进来了
Thread-33进来了
Thread-29走了
Thread-34进来了
Thread-31走了
Thread-30走了
Thread-33走了
Thread-32走了
Thread-37进来了
Thread-36进来了
Thread-35进来了
Thread-38进来了
Thread-34走了
Thread-39进来了
Thread-37走了
Thread-36走了
Thread-35走了
Thread-38走了
Thread-42进来了
Thread-41进来了
Thread-40进来了
Thread-43进来了
Thread-39走了
Thread-44进来了
Thread-41走了
Thread-40走了
Thread-42走了
Thread-43走了
Thread-47进来了
Thread-46进来了
Thread-45进来了
Thread-48进来了
Thread-44走了
Thread-49进来了
Thread-46走了
Thread-48走了
Thread-47走了
Thread-51进来了
Thread-45走了
Thread-52进来了
Thread-50进来了
Thread-53进来了
Thread-49走了
Thread-54进来了
Thread-53走了
Thread-50走了
Thread-55进来了
Thread-51走了
Thread-52走了
Thread-57进来了
Thread-56进来了
Thread-58进来了
Thread-54走了
Thread-59进来了
Thread-57走了
Thread-56走了
Thread-58走了
Thread-55走了
Thread-62进来了
Thread-61进来了
Thread-60进来了
Thread-63进来了
Thread-59走了
Thread-64进来了
Thread-63走了
Thread-60走了
Thread-61走了
Thread-62走了
Thread-67进来了
Thread-66进来了
Thread-65进来了
Thread-68进来了
Thread-64走了
Thread-69进来了
Thread-68走了
Thread-67走了
Thread-66走了
Thread-71进来了
Thread-65走了
Thread-72进来了
Thread-73进来了
Thread-70进来了
Thread-69走了
Thread-74进来了
Thread-73走了
Thread-72走了
Thread-75进来了
Thread-70走了
Thread-71走了
Thread-77进来了
Thread-76进来了
Thread-78进来了
Thread-74走了
Thread-79进来了
Thread-78走了
Thread-75走了
Thread-76走了
Thread-81进来了
Thread-77走了
Thread-82进来了
Thread-80进来了
Thread-83进来了
Thread-79走了
Thread-84进来了
Thread-81走了
Thread-83走了
Thread-85进来了
Thread-80走了
Thread-82走了
Thread-87进来了
Thread-86进来了
Thread-88进来了
Thread-84走了
Thread-89进来了
Thread-87走了
Thread-85走了
Thread-86走了
Thread-88走了
Thread-92进来了
Thread-91进来了
Thread-93进来了
Thread-90进来了
Thread-89走了
Thread-94进来了
Thread-93走了
Thread-90走了
Thread-96进来了
Thread-92走了
Thread-91走了
Thread-97进来了
Thread-98进来了
Thread-95进来了
Thread-94走了
Thread-99进来了
Thread-98走了
Thread-95走了
Thread-96走了
Thread-97走了
Thread-99走了

  可以使用Semaphore控制,首先(构造函数)创建了一个Semaphore对象,并且初始化了5个信号。这样的效果是空间test方法最多只能有5个线程并发访问,对于5个线程时就排队等待,走一个来下一个,请求一个信号(消费一个信号),如果信号被用完了则等待,如果信号被用完了则等待,等待释放一个信号,释放的信号新的线程就可以使用了。

推荐阅读