ThreadGroup实现线程池(笔记)

本文深入剖析了基于ThreadGroup的线程池实现原理,包括线程池的构造方法、线程内部类的设计、任务获取与添加机制,以及如何等待任务完成和关闭线程池。同时,提供了一个简单的线程池使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     JDK提供了线程池,为了了解线程池的运行原理,现在分析一个使用ThreadGroup实现的线程池
1.ThreadGroup
      线程组可以遍历线程,获取活动或非活动的线程
            activeCount()返回线程池组中线程数目
            enumerate(Thread[])列举线程组中的线程
2.下面的线程池实现原理
      构造方法
            传递需要创建的线程数及队列,启动线程
      线程内部类
            Thread的继承,run方法循环执行从队列中取出的任务
      取任务方法
            从队列中取得任务,需要线程安全,供线程调用。如果一个线程取不到,则wait等待notify的唤醒,并是否锁
      添加任务方法
            添加任务到队列中, 添加完notify随机唤醒一个线程,提示有新的任务了
      等待任务完成
            notifyAll唤醒线程,使用了线程组来管理等待线程执行完毕
      关闭线程池
            清空队列,interrupt中断全部线程
3.线程池的使用
      创建线程池,线程池只负责执行,业务逻辑封装成Runnable对象,线程池中的线程通过调用Runnable中的run方法执行

4.参考源码

public class ThreadPool extends ThreadGroup{
	
	// 用于判断线程池是否关闭
	private boolean isClosed = false;
	// 任务队列
	private LinkedList<Runnable> queue;
	// 线程池ID
	private static int threadPoolId;
	// 线程ID
	private int threadId;
	
	// 通过构造方法传递创建线程数
	public ThreadPool(int poolSize){
		super("thread pool -" + threadPoolId++);
		// 设为守护线程
		setDaemon(true);
		// 任务队列
		queue = new LinkedList<Runnable>();
		// 启动线程
		for(int i=0;i<poolSize;i++){
			new WorkThread().start();
		}
	}
	
	
	// 任务执行的线程
	private class WorkThread extends Thread{
		public WorkThread(){
			super("work thread-" + threadId++);
		}
		
		@Override
		public void run() {
			// 如果当前线程没有被中断,当调用了interrupt时线程会中断
			while(!isInterrupted()){
				Runnable task = null;
				// 不断的从任务队列中取得任务
				try {
					task = getTask();
				} catch (InterruptedException e) {
				}
				if(task == null){
					return;
				}
				// 执行任务
				task.run();
			}
		}
	}
	
	
	// 从队列中取任务,取任务需要线程安全,同一个任务只能被一个线程取到
	protected synchronized Runnable getTask() throws InterruptedException{
		while(queue.size()==0){
			// 线程池已经关闭
			if(isClosed){
				return null;
			}
			// 为空,则等待,释放琐
			wait();
		}
		return queue.removeFirst();
	}
	
	
	// 队列中添加任务
	public synchronized void addTask(Runnable task){
		if(isClosed){
			throw new IllegalStateException();
		}
		
		if(task!=null){
			queue.add(task);
			// 已经添加任务,唤醒线程执行,notify并不能确定唤醒哪一个
			// 唤醒wait的线程
			notify();
		}
	}
	
	
	// 等待任务执行完毕
	public void join(){
		// 关闭线程池
		synchronized(this){
			isClosed = true;
			notifyAll();
		}
		
		// activeCount估算正在活动的线程
		Thread[] threads = new Thread[activeCount()];
		// 枚举,获得活动线程的引用,返回活动线程数目
		int count = enumerate(threads);
		for(int i=0;i<count;i++){
			try {
				// 等待线程结束
				threads[i].join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	// 关闭线程池
	public synchronized void close(){
		if(!isClosed){
			isClosed = true;
			queue.clear();
			// 中断线程
			interrupt();
		}
	}
}

      使用线程池执行任务

 

	public static void main(String[] args) throws Exception{
		// 创建线程池
		ThreadPool pool = new ThreadPool(3);
		for(int i=0;i<10;i++){
			pool.addTask(task(i));
		}
		
		// 等待完成,关闭线程池
		pool.join();
		pool.close();
	}
	
	private static Runnable task(final int taskId){
		return new Runnable(){
			@Override
			public void run() {
				System.out.println("第"+taskId+"个任务,开始运行");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("第"+taskId+"个任务,运行结束");
			}
		};
	}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值