java仿写线程池

线程池的作用

  • 避免频繁的创建和销毁线程。
  • 对线程进行管理,避免无休止的消耗系统的资源,而造成系统崩溃。

线程池接口

定义一个线程池接口:规定好线程池的5个基本方法。

public interface ThreadPool  {
    void execute(Job job);
    void shutdown();
    void addWorks(int num);
    void removeWorks(int num);
    int getJobSize();
}
  • execute()方法:想线程池中加入新的任务。
  • shutdown()方法:关闭线程池,将线程池中所有的工作中的线程变为非工作状态。
  • addWorks()方法:在线程池中新建指定数量的工作线程
  • removeWorkers()方法:移除线程池中指定数量的工作线程。
  • getJobSize()方法:返回线程池中未处理的任务数

初始化线程池的基本属性

public class DefaultThreadPool  implements ThreadPool{
 
    //规定线程池的最大线程数
    private static final int MAX_WORKER_NUMBERS=10;
   //规定线程池的默认线程数
    private static final int DEFAULT_WORK_NUMBERS=5;
    //规定线程池的最小线程数
    private static final int MIN_WORKER_NUMBERS=1;
    //用来存放任务的链表
    private final LinkedList jobs=new LinkedList<>();
    //用来存放worker的链表
    private final Listworkers= Collections.synchronizedList(new ArrayList());
    //用来记录创建的是第几个线程,Atomiclong保证数量增加的线程安全性
    private AtomicLong threadNum =new AtomicLong();
    private int workerNum=DEFAULT_WORK_NUMBERS;
    //初始化线程池,开启线程的数量是DEFAULT_WORK_NUMBERS默认值
    public  DefaultThreadPool(){
        initializeWorkers(DEFAULT_WORK_NUMBERS);
    }

    public  DefaultThreadPool(int num){
        this.workerNum=num>MAX_WORKER_NUMBERS?MAX_WORKER_NUMBERS:num

初始化线程池的方法,在初始化线程时自动调用

  /**
     * 初始化线程池的线程的方法,传参num是几就创建几个工作线程,并在创建成功后让这些线程进入就绪态
     * @param num
     */
    private void initializeWorkers(int num){
        for (int i = 0; i < num; i++) {
            Worker worker=new Worker();
            workers.add(worker);
            Thread thread=new Thread(worker,"ThreadPool-Worker-"+threadNum.incrementAndGet());
            thread.start();
        }
    }

实现ThreadPool接口的方法

   /**
     * 添加新的任务到线程池
     * @param job
     */
    @Override
    public void execute(Job job) {
         if(job!=null){
             synchronized (jobs){
                 jobs.addLast(job);
                 //通知其他想要拿取任务的线程,现在可以拿取任务了
                 jobs.notify();
             }
         }
    }

    /**
     * 将全部的工作线程的工作状态变为false,使其不在拿取任务工作。
     */
    @Override
    public void shutdown() {
      for (Worker worker:workers){
          worker.shutdown();
      }
    }

    /**
     * 向线程池中添加新的工作线程
     * @param num
     */
    @Override
    public void addWorks(int num) {
        synchronized (jobs){
            //如果我们想要新建的工作线程数超过了线程池允许的最大线程数,那么就创建到线程池的最大个数
            if((num+workerNum)>MAX_WORKER_NUMBERS){
                num=MAX_WORKER_NUMBERS-workerNum;
            }
            initializeWorkers(num);
            //更新当前的工作线程数
            workerNum+=num;
        }
    }

    /**
     * 移除线程池中的工作线程,数量为num
     * @param num
     */
    @Override
    public void removeWorks(int num) {
        synchronized (jobs){
            //如果我们想要移除的线程数量超过线程池中正在运行的线程数量,抛出异常
            if(num>=workerNum){
                throw new IllegalArgumentException("beyond workNum");
            }
            //count用来记录当前已经成功移除的工作线程的数量
            int count=0;
            while (count

整体代码

package com.example.redisdemo.线程池;

import javafx.concurrent.Worker;
import reactor.core.scheduler.Scheduler;

import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

public class DefaultThreadPool  implements ThreadPool{
    /**
     * Worker类用于从jobs中拿任务然后执行
     */
   class Worker implements Runnable{
       //running表示
       private volatile boolean running=true;
       @Override
       public void run() {
           Job job=null;
           synchronized (jobs){
               while (jobs.isEmpty()){
                   try {
                       jobs.wait();
                   }catch (InterruptedException e){
                       Thread.currentThread().interrupt();
                       return;
                   }
               }
               job=jobs.removeFirst();
           }
           if(job!=null){
               job.run();
           }
       }//shutdown()方法,让worker对象停止工作
       public void shutdown(){
           running=false;
       }

   }
    //规定线程池的最大线程数
    private static final int MAX_WORKER_NUMBERS=10;
   //规定线程池的默认线程数
    private static final int DEFAULT_WORK_NUMBERS=5;
    //规定线程池的最小线程数
    private static final int MIN_WORKER_NUMBERS=1;
    //用来存放任务的链表
    private final LinkedList jobs=new LinkedList<>();
    //用来存放worker的链表
    private final Listworkers= Collections.synchronizedList(new ArrayList());
    //用来记录创建的是第几个线程,Atomiclong保证数量增加的线程安全性
    private AtomicLong threadNum =new AtomicLong();
    private int workerNum=DEFAULT_WORK_NUMBERS;
    //初始化线程池,开启线程的数量是DEFAULT_WORK_NUMBERS默认值
    public  DefaultThreadPool(){
        initializeWorkers(DEFAULT_WORK_NUMBERS);
    }

    public  DefaultThreadPool(int num){
        this.workerNum=num>MAX_WORKER_NUMBERS?MAX_WORKER_NUMBERS:numMAX_WORKER_NUMBERS){
                num=MAX_WORKER_NUMBERS-workerNum;
            }
            initializeWorkers(num);
            //更新当前的工作线程数
            workerNum+=num;
        }
    }

    /**
     * 移除线程池中的工作线程,数量为num
     * @param num
     */
    @Override
    public void removeWorks(int num) {
        synchronized (jobs){
            //如果我们想要移除的线程数量超过线程池中正在运行的线程数量,抛出异常
            if(num>=workerNum){
                throw new IllegalArgumentException("beyond workNum");
            }
            //count用来记录当前已经成功移除的工作线程的数量
            int count=0;
            while (count

你可能感兴趣的:(并发编程面试题,JVM,java,开发语言)