当前位置:首页 > 编程教程 > java技术文章 > java自定义线程池的原理简介

浅析java自定义线程池原理

  • 发布时间:
  • 作者:码农之家
  • 点击:68

这篇文章主要知识点是关于java、线程池、的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

Java编程思想
Java编程思想影印第4版
  • 类型:计算机科学大小:86.6 MB格式:PDF作者:Bruce Eckel
立即下载

java自定义线程池的原理简介

线程池的相关概念就不在这里说明了,百度一下有很多,这里简单表述一下如何实现一个自定义的线程池就行线程管理,我们如果要实现一个线程池对线程的管理,那么需要实现一下几点的思路:

1.如何管理线程

2.如何定义工作线程以及工作线程如何持续的保持运行状态

3.如何定义线程池大小及队列大小

4.如何提供接口给调用者使用

5.如何关闭线程池中的线程

接下来我们就一一的实现这几个问题。

1.我们需要定义一个队列来来管理线程,这里使用了LinkedBlockingQueue

// 1.定义一个存储线程队列 
private LinkedBlockingQueue<Runnable> queue; 

2.因为是一个简单的测试,所以我们可以先定义一个内部类来实现工作线程

// 2.定义工作线程进行线程的执行 
  class Worker extends Thread {  
    private SelfThreadPoolExecutor threadPoolExecutor; 
 
    public Worker(SelfThreadPoolExecutor poolExecutor) { 
      this.threadPoolExecutor = poolExecutor; 
    }  
    @Override 
    public void run() { 
      Runnable task; 
      while (threadPoolExecutor.receiveTask || threadPoolExecutor.queue.size() > 0) { 
        try { 
          // 有线程则取出来,否则等待 
          System.out.println("准备消费线程"); 
          task = threadPoolExecutor.queue.take(); 
          if (task != null) { 
            task.run(); 
            System.out.println("消费线程"); 
          } 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 
    } 
  } 

SelfThreadPoolExecutor是外部定义的整体类名

3.使用有参的构造方法进行线程池大小的管理

// 3.存放工作线程的集合 
  private List<Worker> workerList;  
  // 4.线程池初始化 
  public SelfThreadPoolExecutor(int coreSize, int queueSize) { 
    if (coreSize <= 0 || queueSize <= 0) { 
      throw new IllegalArgumentException("参数不正确"); 
    } 
    this.queue = new LinkedBlockingQueue<>(queueSize); 
    // 线程安全的集合 
    this.workerList = Collections.synchronizedList(new ArrayList<>()); 
    for (int i = 0; i < coreSize; i++) { 
      Worker worker = new Worker(this); 
      worker.start(); 
      workerList.add(worker); 
    } 
  } 

4.定义阻塞和非阻塞的方式提供对应的接口

// 5.非阻塞的方法接口 
  public boolean offer(Runnable task) { 
    if (receiveTask) { 
      return queue.offer(task); 
    } else { 
      return false; 
    } 
  } 
  // 6.阻塞的方法接口 
  public void put(Runnable task) { 
    try { 
      if (receiveTask) { 
        queue.put(task); 
      } 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } 
  } 

6.进行线程池的关闭

// 7.线程池的关闭 
  private boolean receiveTask = true;  
  public void shutdown() { 
    // 7.1.队列不再接收线程 
    receiveTask = false; 
    // 7.2.关闭处于wait或block的线程 
    for (Thread thread : workerList) { 
      if (Thread.State.BLOCKED.equals(thread.getState()) 
      || Thread.State.WAITING.equals(thread.getState()) 
      || Thread.State.TIMED_WAITING.equals(thread.getState())){ 
        thread.interrupt(); 
      } 
    } 
  } 

我们测试的方法如下:

public static void main(String [] args){ 
    SelfThreadPoolExecutor selfThreadPoolExecutor = new SelfThreadPoolExecutor(5,10); 
    for(int i = 0;i < 20;i++){ 
      Runnable task = () ->{ 
        System.out.println("开启线程"); 
      }; 
      selfThreadPoolExecutor.put(task); 
    } 
    selfThreadPoolExecutor.shutdown(); 
  } 

运行结果是:

准备消费线程 
准备消费线程 
准备消费线程 
准备消费线程 
准备消费线程 
开启线程 
消费线程 
准备消费线程 
开启线程 
消费线程 
准备消费线程 
开启线程 
消费线程 
准备消费线程 
。。。。。。 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

Java 相关电子书
学习笔记
网友NO.384528

Java四种常用线程池的详细介绍

一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。 2. 线程池的工作机制 2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。 2.2 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。 3. 使用线程池的原因: 多线程运行时间,系统不断的启动和关闭新线程,成本非常高,会过渡消耗系统资源,以及过渡切换线程的危险……

网友NO.776272

详解Java线程池的增长过程

通过ThreadPoolExecutor的方式创建线程池 ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueRunnable workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { //code... } 参数的意义: 1.corePoolSize 指定了线程池里的线程数量,核心线程池大小 2.maximumPoolSize 指定了线程池里的最大线程数量 3.keepAliveTime 当线程池线程数量大于corePoolSize时候,多出来的空闲线程,多长时间会被销毁。 4.unit 时间单位 5.workQueue 任务队列,用于存放提交但是尚未被执行的任务。 6.threadFactory 线程工厂,用于创建线程,一般可以用默认的 7.handler 拒绝策略,当任务过多时候,如何拒绝任务。当提交任务数超过maximumPoolSize +workQueue 的size之和,任务交给RejectedExecutionHandler 处理 线程池的增长 线程池的增长与创建自定义线程池时设置的……

网友NO.105730

Java并发之串行线程池实例解析

前言 做Android的这两年时间,通过研究Android源码,也会Java并发处理多线程有了自己的一些理解。 那么问题来了,如何实现一个串行的线程池呢? 思路 何为串行线程池呢? 也就是说,我们的Runnable对象应该有个排队的机制,它们顺序从队列尾部进入,并且从队列头部选择Runnable进行执行。 既然我们有了思路,那我们就考虑一下所需要的数据结构? 既然是从队列尾部插入Runnable对象,从队列头部执行Runnable对象,我们自然需要一个队列。Java的SDK已经给我们提供了很好的队列数据结构,例如双端队列:ArrayDequeRunnable。 因为涉及到线程的执行,那我们首先就需要有一个合适的线程池,使用ThreadPoolExecutor类即可构造。 既然是串行执行,那如何保持串行机制呢?我们可以通过try和finally机制,我们将传入的Runnable对象重新封装成一个新的Runnable对象,在新的Ru……

网友NO.735653

基于java线程池读取单个SQL数据库表

任务: 基于线程池来操作MySQL,测试单台机器读写MySQL单表的效率。 思路: 创建一个大小合适的线程池,让每个线程分别连接到数据库并进行读取输出操作。 连接到数据库 import java.sql.DriverManager;import java.sql.SQLException; import com.mysql.jdbc.Statement; public class TEXT { } class MySQLOpen { private Connection con = null; private static String driver = "com.mysql.jdbc.Driver"; private static String url = "jdbc:mysql://localhost:3306/phpmyadmin"; private static String username = "root"; private static String password = "root"; private static Statement NULL = null; public void MysqlOpen() { try { Class.forName(driver); //加载驱动类 con = DriverManager.getConnection(url, username, password); //连接数据库 if (!con.isClosed()) System.out.println("***数据库成功连接***"); } catch (ClassNotFoundException e) { System.out.println("找不到驱动程序类,加载驱动失败"); e.printStackTrace(); } catch (SQL……

网友NO.977622

Java concurrency线程池之线程池原理(二)_动力节点Java学院整理

线程池示例 在分析线程池之前,先看一个简单的线程池示例。 import java.util.concurrent.Executors;import java.util.concurrent.ExecutorService;public class ThreadPoolDemo1 { public static void main(String[] args) { // 创建一个可重用固定线程数的线程池 ExecutorService pool = Executors.newFixedThreadPool(2); // 创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread ta = new MyThread(); Thread tb = new MyThread(); Thread tc = new MyThread(); Thread td = new MyThread(); Thread te = new MyThread(); // 将线程放入池中进行执行 pool.execute(ta); pool.execute(tb); pool.execute(tc); pool.execute(td); pool.execute(te); // 关闭线程池 pool.shutdown(); }}class MyThread extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName()+ " is running."); }} 运行结果: pool-1-thread-1 is running.pool-1-thread-2 is running.pool-1-thread-1 is running.pool-1-thread-2 is running.pool-……

<
1
>

Copyright 2018-2020 www.xz577.com 码农之家

版权投诉 / 书籍推广 / 赞助:520161757@qq.com