`

控制线程数量之-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

分享到:
评论

相关推荐

    Laravel开发-laravel-semaphore

    在计算机科学中,信号量是一种同步机制,用于控制多个进程或线程对共享资源的访问。在Laravel框架中,信号量可以用来限制同时执行某个任务的数量,从而确保系统的稳定性和性能。 `laravel-semaphore`是专门为...

    Swift-dispatch-semaphore

    `DispatchSemaphore`是一种信号量机制,它主要用于线程同步,控制对共享资源的访问。在多线程环境中,当多个线程尝试同时访问同一资源时,信号量可以确保在任何时刻只有一个线程能访问该资源,从而避免数据竞争和不...

    OC-dispatch-semaphore

    在GCD中,它用来限制同时访问某个资源的线程数量。Semaphore有两种类型:二进制semaphore和计数semaphore。在iOS开发中,我们通常使用的是二进制semaphore,它的值只能是0或1,代表资源是否可用。 二、Dispatch ...

    vc++ multithread多线程教程---线程通信--利用事件对象,线程同步--使用信号量,线程同步--使用互斥量,线程同步--使用临界区

    例如,事件对象适合于线程间的复杂通信和协调,信号量可以控制资源的并发访问数量,互斥量适合于独占资源的访问,而临界区则适用于保护小范围的共享数据。理解并熟练运用这些机制,能够帮助开发者编写出高效且线程...

    OS-semaphore.rar_Semaphore_semaphore. windows

    操作系统中的信号量(Semaphore)是一种重要的同步机制,尤其在多任务环境如Windows系统中,它被广泛用于控制多个进程或线程对共享资源的访问。信号量机制源于荷兰计算机科学家Dijkstra提出的银行家算法,其核心思想...

    易语言多线程控制:信号量控制线程数量

    以下是一个简单的示例,展示了如何在易语言中使用信号量控制线程数量: ```易语言 .信号量 = 创建信号量(5, 5) // 初始化一个信号量,初始值和最大值均为5,表示最多有5个线程并发执行 .线程池 = 创建数组(10, ....

    semaphore控制多线程循序执行

    在"semaphore控制多线程循序执行"的场景中,我们通常会用到计数信号量,它的核心作用是限制同时访问特定资源的线程数量。例如,如果我们要实现一个打印队列,让多个线程按顺序打印任务,Semaphore就可以用来保证打印...

    使用信号量(Semaphore)实现线程的同步

    计数信号量的值可以为任何非负整数,可以控制同时访问资源的线程数量。 在实际应用中,信号量常用于以下场景: - **生产者-消费者问题**:生产者线程生成数据并放入缓冲区,而消费者线程则从缓冲区取出数据。通过...

    模拟jdbc多线程竞争资源---【Eclipse项目】

    理解Java的Thread类、Runnable接口以及同步机制(如synchronized关键字、Lock接口、Semaphore等)对于解决多线程问题至关重要。 3. 线程竞争资源: 当多个线程尝试同时修改同一资源时,就会发生资源竞争。在JDBC中...

    15-linux线程专题讲座-王保明.rar

    - 线程创建和销毁开销:过多的线程可能导致资源浪费,应合理控制线程数量。 - 线程同步开销:过度同步可能导致饥饿现象,合理设计同步策略。 9. **线程应用实例**: - Web服务器:通过多线程处理并发请求。 - ...

    C#多线程探索---讲诉多线程

    1. **内存消耗**:线程数量增多意味着更多的内存占用。 2. **CPU负担**:多线程的管理和协调需要额外的CPU时间。 3. **资源共享冲突**:线程间共享资源的访问需妥善管理,以防竞态条件和死锁。 4. **复杂度增加**:...

    Win32 多线程程序设计-线程完全手册--包括例程(Jim Beveridge&Roboert Wiener)

    开发者需要根据系统资源和任务特性合理设计线程数量。 通过阅读《Win32多线程程序设计》这本书,开发者将能深入理解这些概念,并学会如何在实际项目中应用多线程技术,以提高程序的并发能力和性能。书中提供的例程...

    Java多线程实战精讲-带你一次搞明白Java多线程高并发

    - **Semaphore**:信号量,控制同时访问特定资源的线程数量。 10. **并发编程最佳实践** - 避免长时间持有锁,减少锁粒度,提高并发性能。 - 使用并发集合而非普通集合,确保并发安全。 - 合理设置线程池参数,...

    C#语言Semaphore类用法实例(多线程多端口使用端口控制)

    在C#编程中,Semaphore类是线程同步和并发控制的重要工具,主要用于限制对特定资源的并发访问。在这个实例中,我们关注的是如何利用Semaphore来管理多线程对多个端口的访问,确保不会出现冲突。Semaphore类可以看作...

    JAVA线程高级-线程按序交替执行

    - `Semaphore`可以限制同时访问特定资源的线程数量,实现线程按序执行。 - `CyclicBarrier`允许一组线程等待所有线程到达屏障点后一起继续执行,适用于线程间的协同工作。 - `CountDownLatch`通常用于一次性事件...

    多线程demo程序-轻松掌握多线程技术

    通过学习这个"多线程demo程序",你可以掌握如何在实践中创建、管理和控制线程,理解多线程编程的基本概念,以及如何解决可能出现的问题。这个项目中的ThreadProject可能是整个示例代码的主目录,包含了演示这些概念...

    Java多线程Semaphore工具的使用详解.rar

    Java多线程编程是开发高并发应用的关键技术之一,Semaphore工具是Java并发包(java.util.concurrent)中的一个重要组件,用于控制同时访问特定资源的线程数量。本篇将深入讲解Semaphore的基本概念、工作原理以及如何...

    Java多线程与线程安全实践-基于Http协议的断点续传.rar

    线程间的通信和同步是多线程编程的关键,Java提供了多种机制,如wait()、notify()和notifyAll()方法,以及synchronized关键字,用于控制线程的执行顺序和避免竞态条件。 断点续传是HTTP协议的一个高级特性,它允许...

Global site tag (gtag.js) - Google Analytics