自己手写一个线程池

9 篇文章 0 订阅

线程池原理(底下附源码):

 

仓库:接收任务,

卡车:工作线程,从仓库中取任务

当没有任务的时候,工作线程阻塞,当有任务的时候,唤醒工作线程执行

 

 

仓库可以使用blockQueue表示

 

 

 

 

 

 

这些上面是在wangyiyun上面听的课程

 线程池,就是一个放任务线程的地方。工作线程会不断的从线程池中取任务,

手写线程池:

1:创建仓库

2:工作线程集合

3:每一个工作线程需要去做的事情->从仓库中拿任务

4:初始化线程池

5:将任务放入队列

 

package com.thread;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 手写一个线程池
 * 
 * @author Administrator
 *
 */
public class FixedSizeThreadPool {

    // 1:仓库
    private BlockingQueue<Runnable> blockingQueue;

    // 2:线程集合
    private List<Thread> workers;

    // 3:每一个线程要干的事情:从队列(仓库)中拿数据
    public static class Worker extends Thread {
        private FixedSizeThreadPool pool;

        public Worker(FixedSizeThreadPool pool) {
            this.pool = pool;
        }

        @Override
        public void run() {
            while (this.pool.blockingQueue.size() > 0 || this.pool.isWorking) {
                // 到队列拿任务并执行,
                Runnable task = null;
                try {
                    if (this.pool.isWorking) {

                        task = this.pool.blockingQueue.take();// 阻塞
                    } else {
                        task = this.pool.blockingQueue.poll();// 不阻塞

                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (task != null) {
                    task.run();
                    System.out.println("线程" + Thread.currentThread().getName() + "执行完毕");

                }
            }
        }

    }

    /**
     * 初始化线程池
     * 
     * @param poolSize
     *            线程池大小
     * @param taskSize
     *            任务数量
     * @throws IllegalAccessException
     */
    public FixedSizeThreadPool(int poolSize, int taskSize) {
        if (poolSize <= 0 || taskSize <= 0)
            throw new IllegalArgumentException("非法参数");
        this.blockingQueue = new LinkedBlockingDeque<>(taskSize);
        this.workers = Collections.synchronizedList(new ArrayList<>());

        for (int i = 0; i < poolSize; i++) {
            Worker worker = new Worker(this);
            worker.start();
            workers.add(worker);
        }

    }

    // 将任务放入队列
    public boolean submit(Runnable task) {
        if (this.isWorking) {

            return this.blockingQueue.offer(task);
        } else {
            return false;
        }
    }

    // 6:线程池的关闭
    // 关闭的时候总共要分为几步
    // 1:仓库停止接受任务
    // 2:仓库中剩余的任务要执行完
    // 3:去仓库中拿任务额时候,就不应该再阻塞了
    // 4:一旦线程被阻塞了就中断线程
    private volatile boolean isWorking = true;

    public void shutDown() {
        this.isWorking = false;
        for (Thread worker : workers) {
            if (Thread.State.BLOCKED.equals(worker.getState())) {
                worker.interrupt();
            }
        }
    }

    public static void main(String[] args) {
        FixedSizeThreadPool pool = new FixedSizeThreadPool(3, 6);
        for (int i = 0; i < 6; i++) {
            pool.submit(new Runnable() {

                @Override
                public void run() {
                    System.out.println("放入一个任务");

                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });
        }

        pool.shutDown();
    }
}
 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值