自己动手实现简单的线程池

为了节省系统在多线程并发情况下不断的创建新和销毁线程所带来的性能浪费,就需要引入线程池。

线程池的基本功能就是线程复用。每当系统提交一个任务时,会尝试从线程池内取出空闲线程来执行它。如果没有空闲线程,这时候再创建新的线程。任务执行完毕,线程也不会立即销毁,而是加入到线程池中以便下次复用。

Java提供了多种线程池的实现,以满足不同业务的需求。为了理解它们,下面给出一个最简单的线程池的实现。

线程池主要分为两大部分,线程池和一些永不退出的线程

首先是线程池部分:

package optimistic;

import java.util.List;
import java.util.Vector;

public class ThreadPool {
	//使用单例模式创建线程池
	private static ThreadPool pool;

	private final List<PThread> threads;
	private volatile boolean isShutdown;
	private int threadCount = 0;

	// 在线程中调用,用来将自己加入线程池中
	synchronized public void putThread(PThread t) {
		if (!isShutdown) {
			threads.add(t);
		} else {
			t.shutdown();
		}
	}

	// 客户端用来执行自己的一项任务
	synchronized public void start(Runnable task) {
		if (!isShutdown) {
			if (threads.size() < 1) {
				new PThread(task, pool).start();
			} else {
				PThread p = threads.remove(0);
				//设置好
				p.setTarget(task);
			}
		}
	}

	//初始化一个大小为5的线程池数组
	synchronized public static ThreadPool getThreadPool() {
		if (pool == null) {
			pool = new ThreadPool(5);
		}
		return pool;
	}

	public ThreadPool(int poolSize) {
		threads = new Vector<PThread>(poolSize);
		isShutdown = false;
	}

	//如果关闭线程池,需要将所有线程也关闭
	synchronized public void shutdown() {
		for(PThread p : threads)
			p.shutdown();
		threads.clear();
		isShutdown = true;
	}

	public int getThreadCount(){
		return threads.size();
	}
}

其次,我们还需要一个永不退出的线程与之配合。

package optimistic;

public class PThread extends Thread {
	private final ThreadPool pool;
	private volatile boolean isShutdown;
	private Runnable target;

	public PThread(Runnable task, ThreadPool pool) {
		this.target = task;
		this.pool = pool;
		isShutdown = false;
	}

	@Override
	public void run() {
		while (!isShutdown) {
			if (target != null) {
				target.run();
			}
			try {

				pool.putThread(this);
				// 线程执行完任务,会在wait处阻塞,直到 setTarget或者 shutdown 调用notifyAll
				synchronized (this) {
					wait();
				}
			} catch (InterruptedException e) {

			}
		}
	}

	// 每当设置任务或关闭时会唤醒run方法
	synchronized public void setTarget(Runnable r) {
		this.target = r;
		notifyAll();
	}

	synchronized public void shutdown() {
		isShutdown = true;
		notifyAll();
	}

}

完成这主要的两部分之后,我们就只需要定义一个Runnable和一个主线程就好了。

package optimistic;

public class Controller {
	public static void main(String[] args) throws InterruptedException {
		ThreadPool pool = ThreadPool.getThreadPool();
		Runnable r = new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName());
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		for (int i = 0; i < 10; i++)
			pool.start(r);
		Thread.sleep(1500);
		System.out.println(pool.getThreadCount());
		pool.shutdown();
		Thread.sleep(1000);
		System.out.println(pool.getThreadCount());
	}
}
时间: 2025-01-06 00:51:42

自己动手实现简单的线程池的相关文章

一个最简单的线程池

import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /**  * 一个最简单的线程池,这个模型很简单,但是很有用  *  * @author leizhimin 2014/8/22 20:21  */ public class Test3 {     private static final ExecutorService threadPool = Executors.newFix

一个简单的线程池程序设计(消费者和生产者)

最近在学习linux下的编程,刚开始接触感觉有点复杂,今天把线程里比较重要的线程池程序重新理解梳理一下. 实现功能:创建一个线程池,该线程池包含若干个线程,以及一个任务队列,当有新的任务出现时,如果任务队列不满,则把该任务加入到任务队列中去,并且向线程发送一个信号,调用某个线程为任务队列中的任务服务.如果线程池中的线程都在忙,那么任务队列中的任务则等待.本程序较为简单,把任务定义为了两个数相加,输出它们的和. 采用自顶向下的设计方法,先把整体框架构建出来,然后再慢慢把细节,小模块补全. 1.在l

Linux C 一个简单的线程池程序设计

实现功能:创建一个线程池,该线程池包含若干个线程,以及一个任务队列,当有新的任务出现时,如果任务队列不满,则把该任务加入到任务队列中去,并且向线程发送一个信号,调用某个线程为任务队列中的任务服务.如果线程池中的线程都在忙,那么任务队列中的任务则等待.本程序较为简单,把任务定义为了两个数相加,输出它们的和. 采用自顶向下的设计方法,先把整体框架构建出来,然后再慢慢把细节,小模块补全. 1.在linux环境下构建三个文件夹(include,src,bin) include:包含该程序所需要的头文件.

Linux C 实现一个简单的线程池

线程池的定义 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙.如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值.超过最大值的线程可以排队,但他们要等到其他线程完成后才启动. 什么时

一个简单的线程池实现

前段时间学习了线程方面的知识,看了关于线程池的教程,自己也试着实现一个.跟大家分享,同时也整理整理思路.   对线程池的要求: 1.用于处理大量短暂的任务. 2.动态增加线程,直到达到最大允许的线程数量. 3.动态销毁线程.   线程池的实现类似于"消费者--生产者"模型: 用一个队列存放任务(仓库,缓存) 主线程添加任务(生产者生产任务) 新建线程函数执行任务(消费者执行任务) 由于任务队列是全部线程共享的,就涉及到同步问题.这里采用条件变量和互斥锁来实现. ------------

Python简单的线程池

class ThreadPool(object): def __init__(self, max_num=20): # 创建一个队列,队列里最多只能有10个数据 self.queue = queue.Queue(max_num) # 在队列里填充线程类 # [线程类.线程类.线程类.线程类.线程类.线程类.线程类] for i in range(max_num): self.queue.put(threading.Thread) def get_thread(self): # 去队列里去数据,

十五篇、自定义线程池之简单的线程池

1 二. #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 import threading 4 import queue 5 import time 6 7 class ThreadPool(object): 8 def __init__(self,max_num = 20): 9 self.queue = queue.Queue(max_num) #创建一个最大长度为20的队列 10 for i in range(max_num): #往队列里面

一个简单的线程池

/** * * @author hc * @version 1.0 * * @param <Job> */ public interface ThreadPool<Job extends Runnable>{ //执行一个job void execute(Job job); //关闭线程 void shutdown(); //增加工作者线程 void addWorkers(int num); //减少工作者线程 void removeWorkers(int num); //正在等待

手写简单的线程池

线程池的基本原理 声明任务队列.线程数量这两者数量主要由自己init,往队列中添加任务,如果超过数量则等待(阻塞),否则加入线程执行 import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; public cla