Executor和Semaphore 搭建线程池

new Thread()的缺点
调用new Thread()创建的线程缺乏管理,线程之间可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪。
不利于扩展,比如如定时执行、定期执行、线程中断

采用线程池的优点
重用存在的线程,减少对象创建、消亡的开销,性能佳
可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
提供定时执行、定期执行、单线程、并发数控制等功能

Executors工厂类
通过Executors提供四种线程池,newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool。

1.public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。

2.public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线 程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

3.public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。

4.public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService .execute(toDo());

那么问题来了, 我们池子里的线程怎么保证有序性呢?怎么协调各个线程,以保证它们能够正确、合理的使用公共资源的设施呢?

Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。它相当于给线程规定一个量从而控制允许活动的线程数。

Semaphore主要方法:

Semaphore(int permits):构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。

Semaphore(int permits,boolean fair):构造方法,当fair等于true时,创建具有给定许可数的计数信号量并设置为公平信号量。

void acquire():从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。

void acquire(int n):从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。

void release():释放一个许可,将其返回给信号量。就如同车开走返回一个车位。

void release(int n):释放n个许可。

Semaphore在池子里担任的就相当于一个管理员,举个例子:
Semaphore是一家餐厅的经营者, 但由于资金有限, 只能最多每次提供10个餐位供客人就餐,可由于餐厅菜品大受欢迎,客源源源不竭,顾客不得不排队。只有在有人就餐完毕让出餐位后,下一位排队的顾客才能开始点菜就餐。Semaphore就是这样一位杰出的管理者,既能保证顾客有序就餐还能保证餐厅的稳定营业。

下面上code :

int poolSize = 10; //餐厅餐位
ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
Semaphore semaphore = new semaphore(poolSize);
int customer = 0;

public void execute() {
while () {
Thread t1=new eat ();
semaphore.acquire();
executorService .execute(t1);
}
}

private class eat extend Thread{
public void run()
{
try
{
System.out.println(Thread.currentThread().getName()+":大家好,第"+customer +“位顾客就餐完毕 !”+System.currentTimeMillis());
Thread.sleep(1000);
System.out.println(name+“要准备释放许可证了,当前时间为:”+System.currentTimeMillis());
System.out.println(“当前可使用的许可数为:”+semaphore.availablePermits());
semaphore.release();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值