一、Thread与Executors

开启新的线程,我们经常会采用如下方法:

        Thread thread =new Thread(new Runnable() {
@Override
public void run() {
System.out.println("new thread");
}
});

通过new Thread()的方式,会导致很多弊端,如下:

  • 每一次都通过new Thread的方式,性能差。
  • 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致宕机。
  • 缺乏定时执行、定期执行、线程中断等功能。

Executors提供的四种线程池有效的解决以上问题

二、Executors提供的四种线程池

  • newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newScheduledThreadPool 创建一个定长线程池,同时支持定时及周期性任务执行。
  • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。

三、newCachedThreadPool

        ExecutorService executorService1 = Executors.newCachedThreadPool();
Future<String> future = executorService1.submit(new Callable<String>() { @Override
public String call() throws Exception {
return "newCachedThreadPool";
}
});
try {
System.out.println(future.get());
} catch (Exception e) {
e.printStackTrace();
}

四、newFixedThreadPool

        ExecutorService executorService2 = Executors.newFixedThreadPool(3);//定长3个线程
for (int i = 0; i < 10; i++) {
executorService2.execute(new Runnable() {//execute与submit的区别
@Override
public void run() {
try {
System.out.println("定长三个线程");
TimeUnit.SECONDS.sleep(3);//注意和Thread.sleep(3000)的区别
} catch (InterruptedException e) {
System.out.println("InterruptedException");
} catch (Exception e) {
System.out.println("Exception");
}
}
});
}

每隔三秒钟,打印三条数据

五、newScheduledThreadPool

        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);//定长三个线程
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("延迟三秒输出");
}
}, 3, TimeUnit.SECONDS);

延迟三秒输出

        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);//定长三个线程
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("延迟1秒,然后定期每三秒执行一次");
}
},1, 3, TimeUnit.SECONDS);

延迟一秒,然后定期执行

六、newSingleThreadExecutor

        ExecutorService executorService4 = Executors.newSingleThreadExecutor();
for (int i = 1; i < 11; i++) {
//所有被内部类访问的局部变量,都必须使用final修饰
//对于普通局部变量而言,当方法结束以后,该局部变量也就随之消失
//但是匿名内部类的生命周期没有结束的话,将一直可以访问局部变量的值,内部类会扩大局部变量的作用域,会引发混乱
final int index = i;
executorService4.execute(new Runnable() {
@Override
public void run() {
System.out.println("Thread:" + index);
}
});
}

七、其他知识点

7.1、submit与execute的区别

  • submit支持Callable,execute支持Runable
  • submit有返回值,execute无返回值
  • submit可以捕获异常(还是因为支持Callable),execute不可以

7.2、shutdown与shutdownNow的区别

  • shutdown()方法在终止前允许执行正在进行的线程
  • shutdownNow()方法阻止新的进程并试图停止当前正在执行的线程,关闭未使用的 ExecutorService 以允许回收其资源。

最新文章

  1. js晋级篇——前端内存泄漏探讨
  2. jsp项目部署
  3. ASP。net 测验
  4. 如何利用Cloudera Manager来手动安装parcel包
  5. ViewPager的基本使用--可左右循环切换也可自动切换
  6. PHP 5.6正式发布:新特性、及功能改进介绍
  7. Javascript计算密码的强度
  8. RuntimeError: Python is not installed as a framework 错误解决办法
  9. Python 制作Android开发 所需的适配不同分辨率的套图
  10. C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型
  11. Maven(一)简介安装
  12. Django框架之中间件与Auth
  13. 2017 ACM/ICPC Asia Regional Shenyang Online(部分题解)
  14. smali加入日志
  15. 玩转mongodb(七):索引,速度的引领(全文索引、地理空间索引)
  16. 逻辑卷管理-LVM(Logical Volume Manager)
  17. 项目Beta冲刺(团队)第五天
  18. Centos安装自定义布局才能自己划分各个区的大小ctrl+z ,fg ,route -n ,cat !$ ,!cat ,XShell 设置, ifconfig CentOS远程连接 Linux中的输入流 第一节课
  19. 随机森林(Random Forest)
  20. Discuz被挂马 快照被劫持跳转该如何处理 如何修复discuz漏洞

热门文章

  1. MySQL库的相关操作
  2. Django学习笔记 (一) 开发环境配置
  3. js实现图片的Blob base64 ArrayBuffer 的各种转换
  4. English-培训4-How do you spend your day
  5. mongodb副本集和分片存储理论整理
  6. Django+bootstrap+注册登录系统
  7. Linux命令——getent
  8. seo与python大数据结合给文本分词并提取高频词
  9. centOS7 下 安装mysql8.x
  10. unity里blit的load store action设置