当java程序中要用线程处理多个简短任务的时候,使用一种叫做Thread Pooling的技术是很明智的选择。为了不对单个任务逐个创建(并在任务结束时结束)线程,过去我们经常自己编写适合不同运行环境需要的线程池。虽然这些线程池的具体属性参数不尽相同,但是大致都追寻着如下的应用套式:
把任务组引入到线程池里面,
如果线程池中某个线程满足执行条件,立刻执行
任务执行完毕,线程返回线程池
不满足执行条件(比如线程池大小条件),等待执行
J2SE5.0现在提供了全新的java.util.concurrent包,其中有几经构建好的线程池的框架。
例如:Executor接口提供了单独的一个办法execute来接收一个Runnable的实例对象:
public interface Executor {
public void execute(Runnable command);
}
所以我们可以创建一个Executor对象 然后把runnable任务引入:
Executor executor = ...; //可以完成implements后创建...
executor.execute(aRunnable1);
executor.execute(aRunnable2);
例如:
class MyExecutor implements Executor {
public void execute(Runnable r) {
new Thread(r).start();
}
}
在concurrency中还包括一个ThreadPoolExecutor类来提供一般通用用途的线程池操作.下面是4种该类的构造器.我们可以确定该类的某些属性例如: 池的大小,活动时间,线程工厂和被拒绝运行线程控制器.
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue) public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory) public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
public class NamePrinter implements Runnable { private final String name; private final int delay; public NamePrinter(String name, int delay) { this.name = name; this.delay = delay; } public void run() { System.out.println("Starting: " + name); try { Thread.sleep(delay); } catch (InterruptedException ignored) { } System.out.println("Done with: " + name); } } ---------------------------------------------------------------------------------- import java.util.concurrent.*; import java.util.Random; public class UsePool { public static void main(String args[]) { Random random = new Random(); ExecutorService executor = Executors.newFixedThreadPool(3); //设定线程池容量为3 // Sum up wait times to know when to shutdown int waitTime = 500; for (int i=0; i<10; i++) { String name = "NamePrinter " + i; int time = random.nextInt(1000); waitTime += time; Runnable runner = new NamePrinter(name, time); System.out.println("Adding: " + name + " / " + time); executor.execute(runner); } try { Thread.sleep(waitTime); executor.shutdown(); executor.awaitTermination (waitTime, TimeUnit.MILLISECONDS); } catch (InterruptedException ignored) { } System.exit(0); } } ---------------------------------------------------------------------------------- 可能输出: unique with the random sleeps present: Adding: NamePrinter 0 / 30 Adding: NamePrinter 1 / 727 Adding: NamePrinter 2 / 980 //前3个添加进行的明显比较快 Starting: NamePrinter 0 Starting: NamePrinter 1 Starting: NamePrinter 2 Adding: NamePrinter 3 / 409 Adding: NamePrinter 4 / 49 Adding: NamePrinter 5 / 802 Adding: NamePrinter 6 / 211 Adding: NamePrinter 7 / 459 Adding: NamePrinter 8 / 994 Adding: NamePrinter 9 / 459 Done with: NamePrinter 0 虽然任务全部已经添加到线程池, Starting: NamePrinter 3 但是因为线程池容量为3个, Done with: NamePrinter 3 前3个任务又都在执行, Starting: NamePrinter 4 所以任务3一直等到任务0结束才开始执行 Done with: NamePrinter 4 Starting: NamePrinter 5 Done with: NamePrinter 1 Starting: NamePrinter 6 Done with: NamePrinter 6 Starting: NamePrinter 7 Done with: NamePrinter 2 Starting: NamePrinter 8 Done with: NamePrinter 5 Starting: NamePrinter 9 Done with: NamePrinter 7 Done with: NamePrinter 9 Done with: NamePrinter 8
↑返回目录
前一篇: Swing中的getContentPane()方法
后一篇: 如何保护Java程序