|
这次我们来基于java设计并实现一个简单的任务池。
什么叫任务池?
实际上就是一个任务流水线,可以将各种待完成的任务发布到流水线中。由任务池统计管理并且调度,来保证任务的完成。可能会有这样的疑问:我对每个任务都单独起一个线程,让其独立完成不就可以了么?对于小批量、快速、占用少量资源的任务可能这样没有问题,但是对于大规模、多并发的任务,这样的结果是会造成系统性能极其低下,并且还很可能造成资源需求上的溢出。
如何用有限的资源,调度并完成任务,这就是我们任务池的最终目标。
很直观,直接上任务池中就是有一个队列存储任务对象,对于每个任务它能知道当前任务状态(尚未开始、进行中、已完成)。当一个任务完成的时候,它将该任务清除,并且取出一个其他尚未完成的任务并开启之。
任务池应该具有并发性能,可以限制同时最多有多少个任务并行执行。
好,需求明确了,下面直接看代码吧。该代码实现子任务调用FFMPEG进行视频转码,而任务管理池用于限制并调度任务并发的执行。
/**
*
*/
package com.nvvideo.upload.logic;
import java.util.LinkedList;
/**
* TransferManager
* Title: 视频转码任务管理器
* Description:
* Date: 2010-7-14
* Copyright: Copyright (c) 2010
* Company: novel-supertv.com
* @author chenggong
* @version 1.0
*/
public class TransferManager {
private int maxThreadNum = 1;
private LinkedList fileList;
private int workingThreadNum = 0;
public TransferManager(){
this.fileList = new LinkedList();
}
/**
* 设置最大并发数
* @param num
*/
public void setMaxThreadNum( int num ){
this.maxThreadNum = num;
}
/**
* 增加文件转码任务
* @param task
*/
public synchronized void addFileTask( TransferTaskBase task ){
fileList.addFirst(task);
}
/**
* 启动转码任务
*/
public void startTransfer(){
if( workingThreadNum >= maxThreadNum )
return;
else{
transferNext();
}
}
private synchronized TransferTaskBase getNextFile(){
if( fileList.size() == 0 )
return null;
else
return fileList.removeLast();
}
protected synchronized void threadLive(){
workingThreadNum++;
}
protected synchronized void threadFinish(){
workingThreadNum--;
}
/**
* 启动下一个转码任务
*/
public void transferNext(){
TransferTaskBase task = this.getNextFile();
if( task == null ){
return;
}
else{
task.start();
}
}
}
转码任务基类
view plaincopy to clipboardprint?
package com.nvvideo.upload.logic;
import com.nvvideo.logic.VideoLogic;
import com.nvvideo.po.Video;
/**
* TransferTaskBase
* Title: 视频转码任务基类
* Description:
* Date: 2010-7-14
* Copyright: Copyright (c) 2010
* Company: novel-supertv.com
* @author chenggong
* @version 1.0
*/
public abstract class TransferTaskBase extends Thread {
protected TransferManager manager;
/**
* 设置管理器
* @param manager
*/
public void setManager( TransferManager manager ){
this.manager = manager;
}
protected Video video;
protected VideoLogic videoLogic;
public void setVideo( Video video ){
this.video = video;
}
public void setVideoLogic(VideoLogic videoLogic) {
this.videoLogic = videoLogic;
}
protected String originFileUri;
/**
* 设置源文件名
* @param filename
*/
public void setOriginFile( String filename ){
originFileUri = filename;
}
/* (non-Javadoc)
* 开始执行转码任务
* @see java.lang.Thread#run()
*/
final public void run(){
manager.threadLive();
this.execute();
manager.threadFinish();
manager.transferNext();
}
/**
* 执行转码
* 必须以阻塞态执行
*/
protected abstract void execute();
}
调用示例:
transferManager 任务池
task 具体任务
transferManager.addFileTask(task);
transferManager.startTransfer(); |
|