线程池

线程池的思想

  

 线程池的概念与Executors类的应用

  > 创建固定大小的线程池

  > 创建缓存线程池

  > 创建单一线程池(如何实现线程死掉后重新启动?)

关闭线程池

  > shutdown 与 shutdownNow的比较

用线程池启动定时器

  > 调用ScheduleExecutorService 的 schedule 方法,返回的ScheduleFuture对象可以取消任务。

  > 支持间隔重复任务的定时方式,不直接支持决定定时的方法,需要转换成相对时间方式。

  

public class ThreadPoolTest {

    public static void main(String[] args) {
// ExecutorService threadPool = Executors.newFixedThreadPool(3); //创建一个固定大小的线程池,线程池中有3个线程可以同时服务
//缓存线程池 线程池中的线程数是动态变化的,当所有线程处于服务状态时,还有需要被服务的任务,自动增加一个线程进行服务
//当任务执行完毕,线程处于空闲一段时间,超时后则自动回收销毁线程
// ExecutorService threadPool = Executors.newCachedThreadPool();
//创建一个只有一个线程的线程池,当这个线程挂掉时,可以自动生成一个线程来代替
//可以解决一个网上很多人问的问题(如何实现线程死掉后重新启动?)
ExecutorService threadPool = Executors.newSingleThreadExecutor();
for(int i = 0;i<10;i++){ //往线程池中扔10个任务
final int task = i;
threadPool.execute(new Runnable() { //往线程池中扔了一个任务 @Override
public void run() {
for(int j = 0;j<10;j++){
System.out.println(Thread.currentThread().getName()+" is loop of "+ j + "the task of "+task);
}
}
});
}
System.out.println("all of 10 tasks have committed");
//上述代码执行完后 没有结束,线程池中有3个线程一直存在,所以程序不会结束
//可以使用 threadPool.shutdown()
threadPool.shutdown(); //当线程池中线程执行完所有任务,所有线程处于空闲状态时,干掉所有线程,程序自结束
// threadPool.shutdownNow(); //立即把池子中所有线程干掉,无论任务是否干完 }
}
package com.java.juc;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 一、线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外的开销,提高了响应的速度。
*
* 二、线程池的体系结构:
* java.util.concurrent.Executor: 负责线程的使用与调度根接口。
* |--**ExecutorService 子接口:线程池的主要接口
* |--ThreadPoolExecutor 线程池的实现类
* |--ScheduledExecutorService 子接口:负责线程的调度
* |--ScheduledThreadPoolExecutor : 继承 ThreadPoolExecutor 实现ScheduledExecutorService
* 三、工具类:Executors
* ExecutorService newFixedThreadPool() :创建固定大小的线程池。
* ExecutorService newCachedThreadPool(): 创建无限大小的线程池,线程池中线程数量不固定,可根据需求自动更改。
* ExecutorService newSingleThreadPool() : 创建单个线程池,线程池中只有一个线程。
*
* ScheduledExecutorService newScheduledThreadPool() 创建固定大小的线程池,可以延迟或定时的执行任务。
*
*/
public class TestThreadPool {
public static void main(String[] args) {
//1.创建线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
ThreadPoolDemo demo = new ThreadPoolDemo(); //2.为线程池中的线程分配任务
for(int i = 0;i<10;i++){
threadPool.submit(demo);
} //3.关闭线程池
threadPool.shutdown(); //等待现有线程池中的任务之心完毕,关闭线程池,在等待过程中不接收新的任务 }
} class ThreadPoolDemo implements Runnable{
private int i = 0;
@Override
public void run() {
while(i <= 100){
System.out.println(Thread.currentThread().getName() + " : " + i++);
}
}
}

可以在线程池中放一个Callable任务,并且可以过去到返回结果

package com.java.juc;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /**
* 一、线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外的开销,提高了响应的速度。
*
* 二、线程池的体系结构:
* java.util.concurrent.Executor: 负责线程的使用与调度根接口。
* |--**ExecutorService 子接口:线程池的主要接口
* |--ThreadPoolExecutor 线程池的实现类
* |--ScheduledExecutorService 子接口:负责线程的调度
* |--ScheduledThreadPoolExecutor : 继承 ThreadPoolExecutor 实现ScheduledExecutorService
* 三、工具类:Executors
* ExecutorService newFixedThreadPool() :创建固定大小的线程池。
* ExecutorService newCachedThreadPool(): 创建无限大小的线程池,线程池中线程数量不固定,可根据需求自动更改。
* ExecutorService newSingleThreadPool() : 创建单个线程池,线程池中只有一个线程。
*
* ScheduledExecutorService newScheduledThreadPool() 创建固定大小的线程池,可以延迟或定时的执行任务。
*
*/
public class TestThreadPool {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1.创建线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
ThreadPoolDemo demo = new ThreadPoolDemo(); List<Future> futureList = new ArrayList<>(); for(int i = 0; i<10; i++){
Future<Integer> future = threadPool.submit(new Callable<Integer>() {
public Integer call(){
int num = 0;
for(int i = 0;i<=100;i++){
num+=i;
}
return num;
}
});
futureList.add(future);
} for(int i = 0;i<futureList.size();i++){
System.out.println(futureList.get(i).get());
}
// //2.为线程池中的线程分配任务
// for(int i = 0;i<10;i++){
// threadPool.submit(demo);
// } //3.关闭线程池
threadPool.shutdown(); //等待现有线程池中的任务之心完毕,关闭线程池,在等待过程中不接收新的任务
}
} class ThreadPoolDemo implements Runnable{
private int i = 0;
@Override
public void run() {
while(i <= 100){
System.out.println(Thread.currentThread().getName() + " : " + i++);
}
}
}

5050
5050
5050
5050
5050
5050
5050
5050
5050
5050

用线程池启动定时器

Executors.newScheduledThreadPool(3).schedule(
new Runnable() {
@Override
public void run() {
System.out.println("bombing!");
}
},
10,
TimeUnit.SECONDS);

还可以在上述代码中添加固定频率

//固定频率 10秒后触发,每隔两秒后执行一次
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
System.out.println("bombing!");
}
},
10,
2,
TimeUnit.SECONDS);
//在使用scheduleAtFixedRate 时java api没有提供在某个时间点触发,但API中提示可以通过计算,得到触发的事件点
// For example, to schedule at a certain future date,
// you can use: schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS).

Java多线程与并发库高级应用-线程池的更多相关文章

  1. Java多线程与并发库高级应用-java5线程并发库

    java5 中的线程并发库 主要在java.util.concurrent包中 还有 java.util.concurrent.atomic子包和java.util.concurrent.lock子包 ...

  2. Java多线程与并发库高级应用-Callable与Future的应用

    Callable这种任务可以返回结果,返回的结果可以由Future去拿 >Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的. >Completion ...

  3. Java多线程与并发库高级应用-传统线程机制回顾

    1.传统线程机制的回顾 1.1创建线程的两种传统方式 在Thread子类覆盖的run方法中编写运行代码 // 1.使用子类,把代码放到子类的run()中运行 Thread thread = new T ...

  4. Java多线程与并发库高级应用-传统线程同步通信技术

    面试题: 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着又 主线程循环100次,如此循环50次,请写出程序 /** * 子线程循环10次,接着主线程循环100次,接着又回到 ...

  5. Java多线程与并发库高级应用-传统线程互斥技术

     线程安全问题: 多个线程操作同一份数据的时候,有可能会出现线程安全问题.可以用银行转账来解释. 模拟线程安全问题 /** * 启动两个线程分别打印两个名字,名字按照字符一个一个打印 * * @aut ...

  6. Java多线程与并发库高级应用-工具类介绍

    java.util.concurrent.Lock 1.Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互 ...

  7. Java多线程与并发库高级应用-同步集合

    ArrayBlockingQueue LinkedBlockingQueue 数组是连续的一片内存 链表是不连续的一片内存  传统方式下用Collections工具类提供的synchronizedCo ...

  8. Java多线程与并发库高级应用-面试题

    第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日 ...

  9. Java多线程与并发库高级应用-可阻塞的队列

    ArrayBlockQueue 可阻塞的队列 > 队列包含固定长度的队列和不固定长度的队列. > ArrayBlockQueue > 看BlockingQueue类的帮助文档,其中有 ...

随机推荐

  1. 网络/运维工程师visio2013模具图标 绘制漂亮的网络拓扑图 狮子XL工程师美学思想

    visio2013狮子XL自定义运维模具下载: 链接:http://pan.baidu.com/s/1bo779Kz 密码:xh3s 狮子XL 的美学思想: 1,一次痛苦,一生幸福. 之前,在绘制网络 ...

  2. node基础06:回调函数

    1.Node异步编程 Node.js 异步编程的直接体现就是回调. 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了. 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,No ...

  3. 增强for循环(forearch)

    增强for循环是为了简化在遍历数组需要先获得数组的长度或者在遍历集合中的元素的时候需要使用迭代器的操作. 引入时间:JDK1.5 语法格式: for(数据类型 变量 :需要迭代的数组或者集合){ } ...

  4. 浅谈设计模式--装饰者模式(Decorator Pattern)

    挖了设计模式这个坑,得继续填上.继续设计模式之路.这次讨论的模式,是 装饰者模式(Decorator Pattern) 装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对 ...

  5. TinyFrame升级之六:全局日志的设计及实现

    日志记录显然是框架设计中不可或缺的元素,在本框架中,我们将使用log4net作为日志记录的主体.下面来具体说明如何让框架继承log4net,并通过Autofac进行IOC注入. 首先,定义好我们的Lo ...

  6. Expression Blend4经验分享:制作一个简单的图片按钮样式

    这次分享如何做一个简单的图片按钮经验 在我的个人Silverlight网页上,有个Iphone手机的效果,其中用到大量的图片按钮 http://raimon.6.gwidc.com/Iphone/de ...

  7. Windows 部署 Redis 群集

    1,下载Redis for windows 的最新版本,解压到 c:\Redis 目录下备用https://github.com/MSOpenTech/redis/releases当前我使用的是 3. ...

  8. HttpClient4.5 SSL访问工具类

    要从网上找一个HttpClient SSL访问工具类太难了,原因是HttpClient版本太多了,稍有差别就不能用,最后笔者干脆自己封装了一个访问HTTPS并绕过证书工具类. 主要是基于新版本Http ...

  9. 生成短链(网址) ShortUrlLink

    建表 CREATE TABLE [dbo].[ShortUrl]( [Id] [,) NOT NULL, [LongUrl] [nvarchar]() NOT NULL, [BaseUri] [int ...

  10. redis的主从复制,读写分离,主从切换

    当数据量变得庞大的时候,读写分离还是很有必要的.同时避免一个redis服务宕机,导致应用宕机的情况,我们启用sentinel(哨兵)服务,实现主从切换的功能. redis提供了一个master,多个s ...