6、java5线程池之固定大小线程池newFixedThreadPool

 

JDK文档说明:

创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。

 创建方法:

java.util.concurrent.Executors.newFixedThreadPool(int nThreads) 

or

java.util.concurrent.Executors.newFixedThreadPool(int nThreads, ThreadFactory threadFactory) 

 

调用上面2个方法得到的对象为:ExecutorService

JDK自带的例子:

下面给出了一个网络服务的简单结构,这里线程池中的线程作为传入的请求。它使用了预先配置的 Executors.newFixedThreadPool(int) 工厂方法:

class NetworkService implements Runnable {
    private final ServerSocket serverSocket;
    private final ExecutorService pool;

    public NetworkService(int port, int poolSize)  throws IOException {
      serverSocket = new ServerSocket(port);
      pool = Executors.newFixedThreadPool(poolSize);
    }
 
    public void run() { // run the service
      try {
        for (;;) {
          pool.execute(new Handler(serverSocket.accept()));
        }
      } catch (IOException ex) {
        pool.shutdown();
      }
    }
  }

class Handler implements Runnable {
    private final Socket socket;
    Handler(Socket socket) { this.socket = socket; }
    public void run() {
      // read and service request on socket
    }
}

 

主要的方法:

 
boolean awaitTermination(long timeout, TimeUnit unit)
请求关闭、发生超时或者当前线程中断,无论哪一个首先发生之后,都将导致阻塞,直到所有任务完成执行。
List>  invokeAll(Collection> tasks)
执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。
List>
invokeAll(Collection> tasks, long timeout, TimeUnit unit)
执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表。
T
invokeAny(Collection> tasks)
执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。
T
invokeAny(Collection> tasks, long timeout, TimeUnit unit)
执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。
boolean isShutdown()
如果此执行程序已关闭,则返回 true
boolean isTerminated()
如果关闭后所有任务都已完成,则返回 true
void shutdown()
启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
List shutdownNow()
试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
Future
submit(Callable task)
提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
Future submit(Runnable task)
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
Future

submit(Runnable task, T result)
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。

void

execute(Runnable command)
在未来某个时间执行给定的命令。

 

自己写的例子:

 

package com.yzl;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class ThreadPool {
    public static void main(String[] args) {
        fixedThreadPool();
    }
    
    /**
     * 固定大小的线程池
     * 
     * 同时可以处理【参数】个任务,多余的任务会排队,当处理完一个马上就会去接着处理排队中的任务。
     * Callable的任务在后面的blog有更详细的文章说明
     */
    private static void fixedThreadPool(){
        ExecutorService es = Executors.newFixedThreadPool(2);
        //加入5个任务
        for(int i=1 ; i<5; i++){
            final int task = i;
            es.execute(new Runnable() {
                @Override
                public void run() {
                    for(int j=1; j<=2; j++){
                        System.out.println("现在运行的是第【 " + task + "】任务");
                        System.out.println(Thread.currentThread().getName() + "is work , now loop to " + j);
                        if(j==2){
                            System.out.println("任务 【" + task + "】运行完成");
                        }
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
        System.out.println("5个Runnable任务submit完成!!");

        //加入5个Callable任务,该任务执行完后是有返回值的则会发生堵塞,也就是取到5个任务的结果后才会继续往下走
        for(int i=1 ; i<=5; i++){
            final int task = i;
            Future future = es.submit(new Callable() {
                @Override
                public Integer call() throws Exception {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Callable 任务【" + task + "】运行");
                    return new Random().nextInt(100);
                }
            });
            
            //如果注释取结果的代码,则不会堵塞
            /*try {
                System.out.println("任务【" + i + "】返回的结果:" + future.get());
            } catch (Exception  e) {
                e.printStackTrace();
            }*/
        }    
        System.out.println("5个Callable任务submit完成!!" + System.currentTimeMillis() );
        //虽然shutdown方法是等所有任务跑完后才真正停掉线程池,但该方法不会造成堵塞,也就是这代码运行后,下一行代码会立刻运行
        es.shutdown();
        System.out.println("主程序shutdown后退出!!" + System.currentTimeMillis());
        
        //暴力的直接终止线程池
        //es.shutdownNow();
        
        //awaitTermination方法是堵塞式的,只有等真的把线程池停掉才会让程序继续往下执行
        try {
            es.awaitTermination(2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("主程序后awaitTermination退出!!" + System.currentTimeMillis());
    }
}

 

你可能感兴趣的:(6、java5线程池之固定大小线程池newFixedThreadPool)