扩展线程池ThreadPoolExecutor的简单例子

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
//扩展线程池以提供日志和计时功能
public class TimingThreadPool extends ThreadPoolExecutor{
	//需要重写配置型的构造方法
	public TimingThreadPool(int corePoolSize, int maximumPoolSize,
			long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}
	public static void main(String[] args) {
		//默认使用Executors.newCachedThreadPool()的配置方法,过期时间为60秒
		TimingThreadPool pool = new TimingThreadPool(0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
		pool.runTask();
		pool.shutdown();
	}
	//执行任务
	public void runTask(){
		this.execute(new Runnable(){
			@Override
			public void run() {
				System.out.println("我执行了一个任务~");
			}}
		);
	}
	//执行任务之前
	@Override
	protected void beforeExecute(Thread t, Runnable r) {
		super.beforeExecute(t, r);
		System.out.println("执行任务之前~");
	}
	//执行任务之后
	@Override
	protected void afterExecute(Runnable r, Throwable t) {
		super.afterExecute(r, t);
		System.out.println("执行任务之后~");
	}
	//执行任务完成,需要执行关闭操作才会调用这个方法
	@Override
	protected void terminated() {
		super.terminated();
		System.out.println("执行任务完成~");
	}
	/**
	 * 运行结果:
	 *  执行任务之前~
		我执行了一个任务~
		执行任务之后~
		执行任务完成~
	 */
}

上面的是一个程序的简单描述,下面的程序会有实际意义点

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
public class LogThreadPool extends ThreadPoolExecutor{
	public LogThreadPool(int corePoolSize, int maximumPoolSize,
			long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}
	private final AtomicInteger numTasks = new AtomicInteger();//线程个数
	private final AtomicLong totalTimes = new AtomicLong();//所有线程总执行时间
	private ThreadLocal<Long> startTime = new ThreadLocal<Long>();
	
	public static void main(String[] args) {
		ThreadPoolExecutor pool = new LogThreadPool(0, Integer.MAX_VALUE, 60, 
				TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
		Runnable task = new Runnable(){
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName()+"任务正在执行");
				try {
					int rand = new Random().nextInt(1000);
					Thread.sleep(rand);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		int ThreadNum = 5;
		for(int i=0; i<ThreadNum; i++){
			pool.execute(task);
		}
		pool.shutdown();
	}
	
	//在执行给定线程中的给定 Runnable 之前调用的方法
	@Override
	protected void beforeExecute(Thread t, Runnable r) {
		super.beforeExecute(t, r);
		System.out.println(Thread.currentThread().getName()+"任务执行之前..");
		startTime.set(System.currentTimeMillis());
	}
	
	//基于完成执行给定 Runnable 所调用的方法
	@Override
	protected void afterExecute(Runnable r, Throwable t) {
		super.afterExecute(r, t);
		long endTime = System.currentTimeMillis();
		long tasktime = endTime - startTime.get();
		numTasks.incrementAndGet();
		System.out.println(Thread.currentThread().getName()+"任务执行之后运行毫秒数:"+tasktime);
		totalTimes.addAndGet(tasktime);
	}
	
	//当 Executor 已经终止时调用的方法
	@Override
	protected void terminated() {
		super.terminated();
		System.out.println("任务全部完成.......");
		System.out.println("共有几个线程执行:"+numTasks);
		System.out.println("共运行了几毫秒:"+totalTimes.get());
	}
/**
 * 运行结果:
 *  pool-1-thread-1任务执行之前..
	pool-1-thread-1任务正在执行
	pool-1-thread-2任务执行之前..
	pool-1-thread-2任务正在执行
	pool-1-thread-4任务执行之前..
	pool-1-thread-4任务正在执行
	pool-1-thread-3任务执行之前..
	pool-1-thread-3任务正在执行
	pool-1-thread-5任务执行之前..
	pool-1-thread-5任务正在执行
	pool-1-thread-1任务执行之后运行毫秒数:47
	pool-1-thread-3任务执行之后运行毫秒数:407
	pool-1-thread-4任务执行之后运行毫秒数:469
	pool-1-thread-2任务执行之后运行毫秒数:500
	pool-1-thread-5任务执行之后运行毫秒数:703
	任务全部完成.......
	共有几个线程执行:5
	共运行了几毫秒:2126
 */
}


delphi线程池单元文件uThreadPool.pas,用法如下 type TRecvCommDataWorkItem=class(TWorkItem) public // updatetime,addtime:TDateTime; // orderid,ordertype,urljson,loadcount,savepath:string; url,Filename:string; total,order:Integer; _orderid:string; failedcount:Integer; IFCoverFile:Boolean; // 线程处理请求时触发的事件 procedure DealwithCommRecvData(Sender: TThreadsPool; WorkItem: TWorkItem; aThread: TProcessorThread); // 线程初始化时触发的事件 procedure TProcessorThreadInitializing(Sender: TThreadsPool; aThread:TProcessorThread); // 线程结束时触发的事件 procedure TProcessorThreadFinalizing(Sender: TThreadsPool; aThread:TProcessorThread); //任务队列空时触发的事件 procedure TQueueEmpty(Sender: TThreadsPool; EmptyKind: TEmptyKind); end; 先声明一个类 然后用法 FThreadPool := TThreadsPool.Create(nil); // 创建线程池 FThreadPool.ThreadsMin := 10; // 初始工作线程数 FThreadPool.ThreadsMax := 100; // 最大允许工作线程数 AWorkItem := TRecvCommDataWorkItem.Create; ISAllOverLoad:=False; AWorkItem.url:=urljson; AWorkItem.order:=i; AWorkItem.total:=JA.Count; AWorkItem.Filename:=savefilepath; AWorkItem._orderid:=orderid; AWorkItem.IFCoverFile:=IFCoverFile; FThreadPool.AddRequest(AWorkItem,True); // 向线程池分配一个任务 FThreadPool.OnProcessRequest := AWorkItem.DealwithCommRecvData; FThreadPool.OnThreadInitializing := AWorkItem.TProcessorThreadInitializing; FThreadPool.OnThreadFinalizing := AWorkItem.TProcessorThreadFinalizing; FThreadPool.OnQueueEmpty := AWorkItem.TQueueEmpty; 仔细看下线程池单元的函数说明轻松搞定。 procedure TRecvCommDataWorkItem.TQueueEmpty(Sender: TThreadsPool; EmptyKind: TEmptyKind); begin if EmptyKind=ekProcessingFinished then begin try if Assigned(geturl) then //存在的bug 如果下载文件存在的不行 begin //Sleep(200); //激活线程可能会发生在 休眠之前!! ISAl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值