今天学习下Concurrent包内线程池的创建、任务执行和关闭,感觉有不少知识点需要总结和整理。
详见具体代码及注释
详见具体代码及注释
/**
*
*/
package network;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author sean
*
* 来自jdk1.6api的参考代码
* 主要使用线程池的创建、执行、关闭
* @since 2009/06/13
*/
public class NetworkService implements Runnable {
private int nThreads = 10; // 线程池大小为10
private ExecutorService pool; // 线程池对象
private ServerSocket serverSocket;
private static int port = 9999;
/**
* 构造函数,创建serverSocket服务器端并启动 创建固定大小的线程池
*
* @param port
*/
public NetworkService(int port) {
try {
serverSocket = new ServerSocket(port);
System.out.println("server is ruuning on port: " + port);
pool = Executors.newFixedThreadPool(nThreads);
// 启动线程
new Thread(this).start();
Timer timer = new Timer();
TimerTask task = new TimerTask(){
@Override
public void run() {
// TODO Auto-generated method stub
shutdownAndWaitTermination(pool);
}
};
//100s之后关闭线程池,查看具体情况
timer.schedule(task, 10000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 线程运行体, 主要负责执行handler类的一个接收客户端连接的工作
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
pool.execute(new Handler(serverSocket.accept()));
} catch (IOException e) {
// TODO 如果连接异常,关闭线程池,也是关键技术点之一
this.shutdownAndWaitTermination(pool);
}
}
}
/**
* 关闭线程池的具体处理方法
* 1. 先拒绝新客户端连接,当前任务仍旧执行
* 2. shutdownAndNow(), 限定时间或者任务完成,立即关闭当前线程池
* @param pool
*/
private void shutdownAndWaitTermination(ExecutorService pool) {
// 第一阶段,不在接收新的客户端连接
pool.shutdown();
try {
// 等待若干时间给当前已经存在的任务,此处60秒
// 等待全部执行完毕就关闭,或者等待限制时间到来,关闭线程thread.interrupt
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
// 取消当前存在的任务
pool.shutdownNow();
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
pool.shutdownNow();
// 保存中断状态
Thread.currentThread().interrupt();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO 实例化一个对象,开始运行本程序
new NetworkService(port);
}
/**
* 负责接收客户端后,在循环体中打印一个socket的地址
*
* @author sean
*
*/
class Handler implements Runnable {
Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("socket is accepted "
+ socket.getRemoteSocketAddress());
}
}
}