站内搜索: 请输入搜索关键词
当前页面: 图书首页 > Java Threads, Third Edition

10.3 Using a Thread Pool - Java Threads, Third Edition

Previous Section  < Day Day Up >  Next Section

10.3 Using a Thread Pool

To use a thread pool, you must do two things: you must create the tasks that the pool is to run, and you must create the pool itself. The tasks are simply Runnable objects, so that meshes well with a standard approach to threading (in fact, the task that we'll use for this example is the same Runnable task we use in Chapter 9 to calculate a Fibonacci number). You can also use Callable objects to represent your tasks (which we'll do later in this chapter), but for most simple uses, a Runnable object is easier to work with.

The pool is an instance of the ThreadPoolExecutor class. That class implements the ExecutorService interface, which tells us how to feed it tasks and how to shut it down. We'll look at the other aspects of that class in this section, beginning with how to construct it.

package java.util.concurrent;

public class ThreadPoolExecutor implements ExecutorService {

    public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue);

    public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              ThreadFactory threadFactory);

    public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              RejectedExecutionHandler handler);

    public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              ThreadFactory threadFactory,

                              RejectedExecutionHandler handler);

}

The core pool size, maximum pool size, keep alive times, and so on control how the threads within the pool are managed. We describe each of these concepts in our next section.

For now, we can use a constructor to create the tasks and put them in the thread pool:

package javathreads.examples.ch10.example1;



import java.util.concurrent.*;

import javathreads.examples.ch10.*;



public class ThreadPoolTest {



    public static void main(String[] args) {

        int nTasks = Integer.parseInt(args[0]);

        long n = Long.parseLong(args[1]);

        int tpSize = Integer.parseInt(args[2]);



        ThreadPoolExecutor tpe = new ThreadPoolExecutor(

            tpSize, tpSize, 50000L, TimeUnit.MILLISECONDS,

            new LinkedBlockingQueue<Runnable>( ));



        Task[] tasks = new Task[nTasks];

        for (int i = 0; i < nTasks; i++) {

            tasks[i] = new Task(n, "Task " + i);

            tpe.execute(tasks[i]);

        }

        tpe.shutdown( );

    }

}

In this example, we're using the tasks to calculate Fibonacci numbers as we do in Chapter 9. Once the pool is constructed, we simply add the tasks to it (using the execute() method). When we're done, we gracefully shut down the pool; the existing tasks run to completion, and then all the existing threads exit. As you can see, using the thread pool is quite simple, but the behavior of the pool can be complex depending on the arguments used to construct it. We'll look into that in the next section.

    Previous Section  < Day Day Up >  Next Section