使用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`是专门为...
`DispatchSemaphore`是一种信号量机制,它主要用于线程同步,控制对共享资源的访问。在多线程环境中,当多个线程尝试同时访问同一资源时,信号量可以确保在任何时刻只有一个线程能访问该资源,从而避免数据竞争和不...
在GCD中,它用来限制同时访问某个资源的线程数量。Semaphore有两种类型:二进制semaphore和计数semaphore。在iOS开发中,我们通常使用的是二进制semaphore,它的值只能是0或1,代表资源是否可用。 二、Dispatch ...
例如,事件对象适合于线程间的复杂通信和协调,信号量可以控制资源的并发访问数量,互斥量适合于独占资源的访问,而临界区则适用于保护小范围的共享数据。理解并熟练运用这些机制,能够帮助开发者编写出高效且线程...
操作系统中的信号量(Semaphore)是一种重要的同步机制,尤其在多任务环境如Windows系统中,它被广泛用于控制多个进程或线程对共享资源的访问。信号量机制源于荷兰计算机科学家Dijkstra提出的银行家算法,其核心思想...
以下是一个简单的示例,展示了如何在易语言中使用信号量控制线程数量: ```易语言 .信号量 = 创建信号量(5, 5) // 初始化一个信号量,初始值和最大值均为5,表示最多有5个线程并发执行 .线程池 = 创建数组(10, ....
在"semaphore控制多线程循序执行"的场景中,我们通常会用到计数信号量,它的核心作用是限制同时访问特定资源的线程数量。例如,如果我们要实现一个打印队列,让多个线程按顺序打印任务,Semaphore就可以用来保证打印...
计数信号量的值可以为任何非负整数,可以控制同时访问资源的线程数量。 在实际应用中,信号量常用于以下场景: - **生产者-消费者问题**:生产者线程生成数据并放入缓冲区,而消费者线程则从缓冲区取出数据。通过...
理解Java的Thread类、Runnable接口以及同步机制(如synchronized关键字、Lock接口、Semaphore等)对于解决多线程问题至关重要。 3. 线程竞争资源: 当多个线程尝试同时修改同一资源时,就会发生资源竞争。在JDBC中...
- 线程创建和销毁开销:过多的线程可能导致资源浪费,应合理控制线程数量。 - 线程同步开销:过度同步可能导致饥饿现象,合理设计同步策略。 9. **线程应用实例**: - Web服务器:通过多线程处理并发请求。 - ...
1. **内存消耗**:线程数量增多意味着更多的内存占用。 2. **CPU负担**:多线程的管理和协调需要额外的CPU时间。 3. **资源共享冲突**:线程间共享资源的访问需妥善管理,以防竞态条件和死锁。 4. **复杂度增加**:...
开发者需要根据系统资源和任务特性合理设计线程数量。 通过阅读《Win32多线程程序设计》这本书,开发者将能深入理解这些概念,并学会如何在实际项目中应用多线程技术,以提高程序的并发能力和性能。书中提供的例程...
- **Semaphore**:信号量,控制同时访问特定资源的线程数量。 10. **并发编程最佳实践** - 避免长时间持有锁,减少锁粒度,提高并发性能。 - 使用并发集合而非普通集合,确保并发安全。 - 合理设置线程池参数,...
在C#编程中,Semaphore类是线程同步和并发控制的重要工具,主要用于限制对特定资源的并发访问。在这个实例中,我们关注的是如何利用Semaphore来管理多线程对多个端口的访问,确保不会出现冲突。Semaphore类可以看作...
- `Semaphore`可以限制同时访问特定资源的线程数量,实现线程按序执行。 - `CyclicBarrier`允许一组线程等待所有线程到达屏障点后一起继续执行,适用于线程间的协同工作。 - `CountDownLatch`通常用于一次性事件...
通过学习这个"多线程demo程序",你可以掌握如何在实践中创建、管理和控制线程,理解多线程编程的基本概念,以及如何解决可能出现的问题。这个项目中的ThreadProject可能是整个示例代码的主目录,包含了演示这些概念...
Java多线程编程是开发高并发应用的关键技术之一,Semaphore工具是Java并发包(java.util.concurrent)中的一个重要组件,用于控制同时访问特定资源的线程数量。本篇将深入讲解Semaphore的基本概念、工作原理以及如何...
线程间的通信和同步是多线程编程的关键,Java提供了多种机制,如wait()、notify()和notifyAll()方法,以及synchronized关键字,用于控制线程的执行顺序和避免竞态条件。 断点续传是HTTP协议的一个高级特性,它允许...