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

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

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

        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());
	}
}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值