IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java Executors和Executor学习 -> 正文阅读

[Java知识库]java Executors和Executor学习

Executors 工具类

下面主要是Executors支持的生成线程池的方式,主要有下面这些

image.png

executors生成一些常用的线程池方法 4·

(1)newSingleThreadExecutor

  • 创建一个单线程的线程池。
  • 这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。
  • 如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。
  • 此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

(2)newFixedThreadPool

  • 创建固定大小的线程池。
  • 每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。
  • 线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
  • 如果希望在服务器上使用线程池,建议使用 newFixedThreadPool方法来创建线程池,这样能获得更好的性能。

(3) newCachedThreadPool

  • 创建一个可缓存的线程池。
  • 如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60 秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。
  • 此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说 JVM)能够创建的最大线程大小。

(4)newScheduledThreadPool

  • 创建一个大小无限的线程池。
  • 此线程池支持定时以及周期性执行任务的需求。

Executor框架

Executor

  • Java 5+中的 Executor 接口定义一个执行线程的工具。
    • 它的子类型即线程池接口是 ExecutorService

什么是 Executor 框架?为什么使用 Executor 框架?

  • Executor 框架是一个根据一组执行策略调用,调度,执行和控制的异步任务的框架。
  • 每次执行任务创建线程 new Thread()比较消耗性能,创建一个线程是比较耗时、耗资源的,而且无限制的创建线程会引起应用程序内存溢出。
  • 所以创建一个线程池是个更好的的解决方案,因为可以限制线程的数量并且可以回收再利用这些线程。利用Executors 框架可以非常方便的创建一个线程池。

在 Java 中 Executor 和 Executors 的区别?

Executors 工具类的不同方法按照我们的需求创建了不同的线程池,来满足业务的需求。
Excutors:使用 ThreadPoolExecutor 可以创建自定义线程池

Executor 接口对象能执行我们的线程任务。
Executor :ExecutorService 接口继承了 Executor 接口并进行了扩展,提供了更多的方法我们能获得任务执行的状态并且可以获取任务的返回值。

Future 表示异步计算的结果,他提供了检查计算是否完成的方法,以等待计算的完成,并可以使用 get()方法获取计算的结果。

image.png

public interface Executor {
    void execute(Runnable command);
}

线程池中 submit() 和 execute() 方法有什么区别?

接收参数

  • execute()只能执行 Runnable 类型的任务。
  • submit()可以执行 RunnableCallable 类型的任务。

返回值

  • submit()方法可以返回持有计算结果的 Future 对象,
  • 而execute()没有

异常处理:submit()方便Exception处理

execute案例

package threadPool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecuteTest {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        for (int i = 0; i < 3; i++) {
            //只能使用Runnable
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"执行线程");
                }
            });
        }
        

    }
}

执行结果:

pool-1-thread-1执行线程
pool-1-thread-2执行线程
pool-1-thread-1执行线程

这里可以发现,线程只有2个,而不是生成3个,是因为使用Executors.newFixedThreadPool 定义线程数量为2

submit案例

package threadPool;

import java.util.concurrent.*;

/**
 * @Author: WalkerShen
 * @DATE: 2022/3/22
 * @Description: 使用submit
 **/
public class SubmitTest {


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //定义线程池工具类
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        //使用submit Runnable方法
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行runnable线程");
            }
        });
        
        
        //使用Callable
        MyCallable myCallable = new MyCallable();
        
        //有执行结果
        Future<Integer> future = executorService.submit(myCallable);
        System.out.println("Callable返回结果"+future.get());


    }
}

class MyCallable implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"执行callable");
        return 2;
    }
}

执行结果

pool-1-thread-1执行runnable线程
pool-1-thread-2执行callable
Callable返回结果2

可以发现,使用submit有以下的不同

  • 可以抛出异常
  • 可以获取Future获取返回结果
  • 可以使用Runnable或者Callable

源码解析

newFixedThreadPool

  public static ExecutorService newFixedThreadPool(int nThreads) {
      //1、nThreads 线程的数量  这里的corePoolSize和maximumPoolSize一致
      //2、new LinkedBlockingQueue<Runnable>()  工作队列
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

ThreadPoolExecutor

底层还是使用了ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
    
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        //异常处理
    if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
   
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
    
    
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

主要参数有以下:

int corePoolSize,  //核心线程数量
int maximumPoolSize, //最大线程数量
long keepAliveTime, //保持alive时间
TimeUnit unit, //单位
BlockingQueue<Runnable> workQueue, //工作队列
ThreadFactory threadFactory, //线程工厂
RejectedExecutionHandler handler //拒绝策略
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:21:19  更:2022-03-24 00:22:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:42:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码