当前位置: 首页 > news >正文

各类网站建设宣传策划方案模板

各类网站建设,宣传策划方案模板,自主建网站,沧州做公司网页的公司有哪些目录 一.上节复习 1.阻塞队列 二.线程池 1.什么是线程池 2.为什么要使用线程池 3.JDK中的线程池 三.工厂模式 1.工厂模式的目的 四.使用线程池 1.submit()方法 2.模拟两个阶段任务的执行 五.自定义一个线程池 六.JDK提供线程池的详解 1.如何自定义一个线程池? 2.创…

目录

一.上节复习

1.阻塞队列

二.线程池

1.什么是线程池

2.为什么要使用线程池

3.JDK中的线程池

三.工厂模式

1.工厂模式的目的

四.使用线程池

1.submit()方法

2.模拟两个阶段任务的执行

五.自定义一个线程池

 六.JDK提供线程池的详解

1.如何自定义一个线程池?

 2.创建线程池的构造方法的参数及含义

3.描述线程池的工作原理

4.拒绝策略

5.为什么不推荐使用系统自带的线程池

七.自定义线程池

1.自定义线程池

 2.拒绝策略测试


一.上节复习

上节内容指路:Java之阻塞队列和消息队列

1.阻塞队列

基于阻塞队列和生产者消费者模型可以实现消息队列

wait()和notify()使用的时机

虚假唤醒:把wait()的判断条件放在一个while循环里面,唤醒之后需要重新检查等待条件

二.线程池

1.什么是线程池

JDBC编程中,通过DataSource获取Connection就用到了池(数据库连接池)的概念                          数据库连接池中有一些已经建立了连接(输入完账号密码的状态)的connection

 当Java程序需要数据库连接时,只需要从数据库连接池中获取到一个空闲的连接进行使用

当Java程序使用完连接之后,就会将当前连接返还给数据库连接池

线程池里放的是线程本身,当程序启动时就创建若干个线程,如果有任务就处理,没有任务就阻塞等待.

2.为什么要使用线程池

为了减少系统创建线程的开销

如果我们不使用线程池,每一次使用创建线程,销毁线程(用户态到内核态),很浪费系统的资源,而且再多线程的环境下,我们一次使用可能是多个线程,多个一起创建很浪费系统的资源,大大减少了系统执行的效率.使用线程池,每一次到池中拿到一个线程,只需要涉及到用户态的操作.

3.JDK中的线程池

1. 用来处理大量短时间工作任务的线程池,如果池中没有可用的线程将创建新的线程,如果线程空闲60秒将收回并移出缓存
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

2. 创建一个操作无界队列且初始线程数为n的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

无界队列: 指的是对队列中的元素个数不加限制,可能出现内存被消耗殆尽的情况

3. 创建一个操作无界队列且只有一个工作线程的线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

4. 创建一个单线程执行器,可以在给定时间后执行或定期执行。
 ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();

5. 创建一个指定大小的线程池,可以在给定时间后执行或定期执行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

6. 创建一个指定大小(不传入参数,为当前机器CPU核心数)的线程池,并行地处理任务不保证处理顺序
ExecutorService executorService = Executors.newWorkStealingPool();

三.工厂模式

1.工厂模式的目的

解决构造方法创建对象的缺陷

以下情况会发生问题,(id,name)和(age,name)会出现相同的参数列表不能够重载,因此不能同时书写这两个构造方法

 我们可以通过两个静态方法来进行创建

class Student {private int id;private int age;private String name;public static Student createByIdAndName(int id, String name) {Student student = new Student();student.setId(id);student.setName(name);return student;}public static Student createByAgeAndName(int age, String name) {Student student = new Student();student.setAge(age);student.setName(name);return student;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

四.使用线程池

1.submit()方法

通过submit方法可以看出我们可以提交任务到线程池,线程池中提供线程进行执行任务.

2.模拟两个阶段任务的执行

public class Demo03_ThreadPoolUse {public static void main(String[] args) throws InterruptedException {//创建一个初始大小为3的线程池ExecutorService threadPool = Executors.newFixedThreadPool(3);for (int i = 0; i < 10; ++i) {int taskId = i;threadPool.submit(() -> {System.out.println("我是任务:" + taskId+","+Thread.currentThread().getName());});}//模拟线程等待一段时间TimeUnit.SECONDS.sleep(5);System.out.println("第二阶段开始");for (int i = 10; i < 20; ++i) {int taskId = i;threadPool.submit(() -> {System.out.println("我是任务:" + taskId+","+Thread.currentThread().getName());});}}
}

打印的内容:

注意:此时程序并没有结束,在等待其他任务提交到线程池进行执行

五.自定义一个线程池

1.可以提交任务到线程池,那么就需要一种数据结构来保存任务----可以考虑使用阻塞队列
2.创建线程池需要指定初始的线程数量,这些线程不断的扫描阻塞队列,如果有任务就立即执行.

可以考虑使用线程池对象的构造方法,接收要创建线程的数据并在构造方法中完成线程的创建

public class MyThreadPool {//定义一个阻塞队列来保存要执行的任务BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(3);//提供一个方法,用来提交任务public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}//构造方法完成线程的初始化public MyThreadPool(int capacity) {if (capacity <= 0) {throw new IllegalArgumentException("capacity is illegal");}//完成线程的创建,扫描队列,取出任务并执行for (int i = 0; i < capacity; i++) {Thread thread = new Thread(() -> {while (true) {//取出任务try {Runnable take = queue.take();take.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();}}
}

测试自定义的线程池:

public class Demo04_MyThreadPool {public static void main(String[] args) throws InterruptedException {//创建一个初始大小为3的线程池MyThreadPool threadPool = new MyThreadPool(3);for (int i = 0; i < 10; ++i) {int taskId = i;threadPool.submit(() -> {System.out.println("我是任务:" + taskId + "," + Thread.currentThread().getName());});}//模拟线程等待一段时间TimeUnit.SECONDS.sleep(2);System.out.println("第二阶段开始");for (int i = 10; i < 20; ++i) {int taskId = i;threadPool.submit(() -> {System.out.println("我是任务:" + taskId + "," + Thread.currentThread().getName());});}}
}

打印结果:

 六.JDK提供线程池的详解

1.如何自定义一个线程池?

通过工厂方法获得的线程池最终都是创建一个ThreadPoolExecutor对象

 2.创建线程池的构造方法的参数及含义

  1. int corePoolSize  核心线程数,创建线程是包含的最小线程数
  2. int maximumPoolSize  最大线程数,也叫临时线程数(核心线程数不够时,允许创建最大的线程数)
  3. long keepAliveTime  临时空闲时长,超过这个时间自动释放
  4. TimeUnit unit   空闲的时间单位,和keepAliveTime一起使用
  5. BlockingQueue<Runnable> workQueue 用来保存任务的阻塞队列
  6. ThreadFactory threadFactory  线程工厂,如何去创建线程
  7. RejectedExecutionHandler handler  拒绝策略,触发的时机,当线程池处理不了过多的任务

3.描述线程池的工作原理

即上面七个参数如何搭配使用

先来举一个现实中的例子帮助我们理解工作原理:饭店老板根据人流量安排桌子数(线程数)

1.饭店里面初始有五张桌子(核心线程数为5)

2.下午3点,人数少于5,5张桌子足够接待顾客(核心线程数大于任务数)

3.到了晚饭点,人数大于5,不够接待顾客,顾客需要拿号排队等待(向阻塞队列加入任务)

4.排号人数过多,老板在饭店门口临时加了10张桌子(创建10个临时线程)

5.在用餐高峰期,门口10张桌子全部用完,排号也特别多,就让新来的顾客下次再来(执行拒绝策略)

6.当人数减少,门口10张桌子空了下来,过了半小时还没人来,将10张桌子回收(临时线程达到空闲时常,回收临时线程)

  1. 当任务添加到线程池中时,先判断任务数是否大于核心线程数,如果不大于,直接执行任务
  2. 任务数大于核心线程数,则加入阻塞队列
  3. 当阻塞队列满了之后,会创建临时线程,会按照最大线程数,一次性创建到最大线程数
  4. 当阻塞队列满了并且临时线程也创建完成,再提交任务,就会执行拒绝策略.
  5. 当任务减少,临时线程达到空闲时长时,会被回收.

4.拒绝策略

AbortPolicy:直接拒绝任务的加入,并且抛出RejectedExecutionException异常

CallerRunsPolicy:返回给提交任务的线程执行

DiscardOldestPolicy:舍弃最老的任务

DiscardPolicy:舍弃最新的任务

根据自己的业务场景选择合适的拒绝策略

5.为什么不推荐使用系统自带的线程池

1.由于使用了无界队列,可能会有内存耗尽的风险

默认是长度最大的阻塞队列


2.临时线程数无法控,也可能会存在资源耗尽

七.自定义线程池

1.自定义线程池

public class Demo_05_Create {public static void main(String[] args) throws InterruptedException {//创建线程池并指定参数ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS,new LinkedBlockingQueue<>(10), new ThreadPoolExecutor.AbortPolicy());for (int i = 0; i < 10; ++i) {int taskId = i;threadPool.submit(() -> {System.out.println("我是任务:" + taskId + "," + Thread.currentThread().getName());});}//模拟线程等待一段时间TimeUnit.SECONDS.sleep(5);System.out.println("第二阶段开始");for (int i = 10; i < 20; ++i) {int taskId = i;threadPool.submit(() -> {System.out.println("我是任务:" + taskId + "," + Thread.currentThread().getName());});}}
}

 2.拒绝策略测试

1.AbortPolicy

将阻塞队列的大小改为1,然后在执行方法

2.CallerRunsPolicy

返回给调用者main方法线程

3.DiscardOldestPolicy

抛弃了一部分的任务,老的

4.DiscardPolicy

抛弃了一部分的任务,新的

http://www.yayakq.cn/news/234872/

相关文章:

  • 户外旅游网站排名苏州建网站
  • 营销行网站建设网站服务商
  • 做网站推广需要多少钱ui设计较好的网站
  • 网站建设公司好哪家好wordpress批量修改图片标题
  • 网站建设实施方案ppt网站域名要多少钱
  • 做视频网站技术壁垒在哪里网上推广平台
  • 富阳建设局网站电话百度关键词价格计算
  • 哈尔滨自助建站平台2021世界500强企业
  • 建立网站有免费的吗潍坊英文网站建设
  • 网站建设相关的广告标语大连网站建设推广
  • 有什么好的提供外链网站湛江网站建设皆选小罗23
  • 莆田哪里有做网站的但不是网络营销的全部
  • 网站建设怎么办制作二维码的方法
  • 网站快速被百度收录asp.net网站配置文件
  • 公司注销后 网站备案外贸网站搭建推广
  • 网站建设实验分析网站建设可行性
  • 广饶网站设计thinkphp企业网站系统
  • 网站招聘栏怎么做seo排名点击器原理
  • 白云区网站建设mg126包装设计网站是什么样子的
  • 网站名称管理个旧市建设网站
  • 云阳如何做网站如何推广自己成为网红
  • 多用户网站管理系统wordpress简介
  • 文山做网站的地方网站关键词优化办法
  • 网站备案被恶意注销58同城找房子租房
  • 解析域名就可以做网站宁波外客网络科技有限公司
  • 台州企业做网站网站没有备案 合法吗
  • 网站建设图片教程视频苏州企业建设网站公司
  • 简单个人网站欣赏国外出名设计网站有哪些
  • 徐州手机网站优化公司前端开发语言的特点是
  • 影楼手机网站设计医院网站建设需要注意什么