JAVA API
有时服务器请求过多,需要使用队列来处理
队列就好比去窗口(线程池)排队买票,窗口也是一种资源,过多的窗口(线程)反而会降低效率。
预先定义好N个窗口 在让每个窗口从队列中取排队等待的人进行处理。性能才会最大化
java1.5加入了队列处理见
Executors 和ExecutorService类
以下示例
public class TheadPool {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们
// ExecutorService threadPool = Executors.newCachedThreadPool();
//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程
// ExecutorService threadPool = Executors.newSingleThreadExecutor();
//创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程
ExecutorService threadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int tasId=i;
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<10;j++)
System.out.println(Thread.currentThread().getName()+ " is loop of "+ tasId);
}
});
}
threadPool.shutdown();
// threadPool.shutdownNow();
}
}
接口 ExecutorService
-
所有超级接口:
- Executor
-
所有已知子接口:
- ScheduledExecutorService
public interface ExecutorService extends Executor
Executor
提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成Future
的方法。
可以关闭 ExecutorService,这将导致其拒绝新任务。提供两个方法来关闭 ExecutorService。shutdown()
方法在终止前允许执行以前提交的任务,而shutdownNow()
方法阻止等待任务启动并试图停止当前正在执行的任务。在终止时,执行程序没有任务在执行,也没有任务在等待执行,并且无法提交新任务。应该关闭未使用的ExecutorService 以允许回收其资源。
通过创建并返回一个可用于取消执行和/或等待完成的 Future
,方法submit 扩展了基本方法Executor.execute(java.lang.Runnable)
。方法invokeAny 和invokeAll 是批量执行的最常用形式,它们执行任务 collection,然后等待至少一个,或全部任务完成(可使用ExecutorCompletionService
类来编写这些方法的自定义变体)。
Executors
类提供了用于此包中所提供的执行程序服务的工厂方法。
用法示例
下面给出了一个网络服务的简单结构,这里线程池中的线程作为传入的请求。它使用了预先配置的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 } }下列方法分两个阶段关闭 ExecutorService。第一阶段调用 shutdown 拒绝传入任务,然后调用 shutdownNow(如有必要)取消所有遗留的任务:
void shutdownAndAwaitTermination(ExecutorService pool) { pool.shutdown(); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { pool.shutdownNow(); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled if (!pool.awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } } catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted pool.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); } }
内存一致性效果:线程中向 ExecutorService
提交 Runnable
或 Callable
任务之前的操作happen-before 由该任务所提取的所有操作,后者依次happen-before 通过Future.get()
获取的结果。
-
从以下版本开始:
- 1.5