总结线程池

虽然创建销毁线程比创建进程更加轻量,但是在频繁创建销毁的时候还是会比较低效

线程池就是为了解决这个问题,如果其中某个线程不再使用了,并不是正真把线程释放,而是放到"另一个池子"中,下次如果需要用到线程就直接从池子中取,不必通过系统来创建了

ExecutorsService和Executors

代码示例:

ExecutorsService表示一个线程池实例

Executors是一个工厂类,能够创建出几种不同风格的线程池

ExecutorsService的submit方法能够向线程池中提交若干个任务

ExecurorService Pool = Executors.newFixedThreadPool(10);
pool.submit(new Runnable() {
@Override
public void run() {
System.out.println("hello");
  }
});

Executors 创建线程池的几种方式

 newFixedThreadPool:创建固定线程数的线程池

newCachedThreadPool:创建线程数目动态增长的线程池

newSingleThreadExecutor:创建只包含单个线程的线程池

newScheduledThreadPool:设定 延迟时间后执行命令,或者定期执行命令,是进阶版的Timer

Executors本质上是ThreadPoolExecutor类的封装

ThreadPoolExecutor

ThreadPoolExecutor提供了更多的可选参数,可以进一步细化参数线程池行为的设定

ThreadPoolExecutor的构造方法

理解ThreadPoolExecutor构造方法的参数

把创建一个线程池想象成开个公司,每个员工相当于一个线程

 

keepAliveTime:临时工允许的空闲时间

unit:keepaliveTime的时间的单位,是秒,分钟,还是其他值

 

 

代码示例:

ExecutorService pool = new ThreadpoolExecutor(1,2,1000,TimeUnit.MILLISECONDS,
                                                  new SynchronousQueue<Runnable<(),
                                                Executors.defaultThreadFactory(),
                                                new
ThreadPoolExecutor.AbortPolicy());
for(int i = 0;i<3;i++) {
pool.submit(new Runnable() {
@Override
void run() {
System.out.println("hello");
    }
 });
}

线程池的工作流程

信号量Semaphore

信号量,用来表示"可用资源的个数"本质上就是一个计时器

理解信号量:

可以把信号量想象成停车场的展示牌,当前有一百个车位,表示有100个可用资源,当有车开进去的时候,就相当于申请一个可用资源,可用车位就-1(这个称为信号量的p操作)

当有车开出来的时候,就相当于释放一个可用资源,可用车位就+1(这个称为信号量的v操作)

如果计数器的值已经为0了,还尝试申请资源,就会阻塞等待,知道有其他线程释放资源

Semaphore的pv操作中的加减计数器操作都是原子的,可以在多线程下直接使用

代码示例:

创建Semaphore示例,初始化为4个可用资源

acquire方法表示申请资源(p操作),release方法表示释放资源(v操作)

创建20个线程,每个线程都尝试申请资源,sleep1秒之后,释放资源,观察程序的执行效果

Semaphroe semphroe = new Semaphroe(4);

Runnable runnable = new Runnable() {
  @Override
public void run() {
  try {
System.out.println("申请资源");
semaphore.acquire();
System.out.println("我获取到了资源");
Thread.sleep(1000);
System.out.println("我释放了资源");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
  }
 }
};

for(int i = 0;i<20;i++) {
Thread t = new Thread(runnable);
t.start();
}

CountDownLatch

同时等待N个任务执行结束:

好像跑步比赛,10个选手依次就位,哨声响才同时出发,所有选手都通过终点,才能公布成绩

构造CountDownLatch实例,初始化10表示有10个任务需要完成

每个任务执行完毕,都调用latch.countDown(),在CountDown Latch内部的计数器同时自减

主线程使用latch.await();阻塞等待所有执行完毕,相当于计数器为0了

public class Demo {
  public static void main(String[] args) throws Exception{
   CountDowlLatch latch = new CountDownLatch(10);
   Runnable r = new Runnable() {
      @Override
   public void run() {
    try {
          Thread.sleep(Match.random() * 10000);
           latch.countDown();
   } catch (Exception e) {
      e.printStackTrace();
      }
   }
};
  for (int i = 0;i<10;i++) {
   new Thread(r).start();
}
//必须等到10人全部回来
latch.await();
System.out.println("比赛结束");
 }
}

 

  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值