java网络编程精解_Java网络编程精解之ServerSocket用法详解二(4)

如例程3-8所示,EchoServer利用线程池ThreadPool来完成与客户的通信任务。

例程3-8  EchoServer.java(使用线程池ThreadPool类)

package multithread2;

import java.io.*;

import java.net.*;

public class EchoServer {

private int port=8000;

private ServerSocket serverSocket;

private ThreadPool threadPool;      //线程池

private final int POOL_SIZE=4;      //单个CPU时线程池中工作线程的数目

public EchoServer() throws IOException {

serverSocket = new ServerSocket(port);

//创建线程池

//Runtime的availableProcessors()方法返回当前系统的CPU的数目

//系统的CPU越多,线程池中工作线程的数目也越多

threadPool= new ThreadPool(

Runtime.getRuntime().availableProcessors() * POOL_SIZE);

System.out.println("服务器启动");

}

public void service() {

while (true) {

Socket socket=null;

try {

socket = serverSocket.accept();

threadPool.execute(new Handler(socket));   //把与客户通信的任务交给线程池

}catch (IOException e) {

e.printStackTrace();

}

}

}

public static void main(String args[])throws IOException {

new EchoServer().service();

}

}

/** 负责与单个客户通信的任务,代码与3.6.1节的例程3-5的Handler类相同 */

class Handler implements Runnable{…}

在以上EchoServer的service()方法中,每接收到一个客户连接,就向线程池ThreadPool提交一个与客户通信的任务。ThreadPool把任务加入到工作队列中,工作线程会在适当的时候从队列中取出这个任务并执行它。

3.6.3  使用JDK类库提供的线程池

java.util.concurrent包提供了现成的线程池的实现,它比3.6.2节介绍的线程池更加健壮,而且功能也更强大。如图3-4所示是线程池的类框图。

105245676.jpg

图3-4  JDK类库中的线程池的类框图

Executor接口表示线程池,它的execute(Runnable task)方法用来执行Runnable类型的任务。Executor的子接口ExecutorService中声明了管理线程池的一些方法,比如用于关闭线程池的shutdown()方法等。Executors类中包含一些静态方法,它们负责生成各种类型的线程池ExecutorService实例,如表3-1所示。

表3-1  Executors类生成的ExecutorService实例的静态方法

Executors类的静态方法

创建的ExecutorService线程池的类型

newCachedThreadPool()

在有任务时才创建新线程,空闲线程被保留60秒

newFixedThreadPool(int nThreads)

线程池中包含固定数目的线程,空闲线程会一直保留。参数nThreads设定线程池中线程的数目

newSingleThreadExecutor()

线程池中只有一个工作线程,它依次执行每个任务

newScheduledThreadPool(int corePoolSize)

线程池能按时间计划来执行任务,允许用户设定计划执行任务的时间。参数corePoolSize设定线程池中线程的最小数目。当任务较多时,线程池可能会创建更多的工作线程来执行任务

newSingleThreadScheduledExecutor()

线程池中只有一个工作线程,它能按时间计划来执行任务

如例程3-9所示,EchoServer就利用上述线程池来负责与客户通信的任务。

例程3-9  EchoServer.java(使用java.util.concurrent包中的线程池类)

package multithread3;

import java.io.*;

import java.net.*;

import java.util.concurrent.*;

public class EchoServer {

private int port=8000;

private ServerSocket serverSocket;

private ExecutorService executorService;    //线程池

private final int POOL_SIZE=4;      //单个CPU时线程池中工作线程的数目

public EchoServer() throws IOException {

serverSocket = new ServerSocket(port);

//创建线程池

//Runtime的availableProcessors()方法返回当前系统的CPU的数目

//系统的CPU越多,线程池中工作线程的数目也越多

executorService= Executors.newFixedThreadPool(

Runtime.getRuntime().availableProcessors() * POOL_SIZE);

System.out.println("服务器启动");

}

public void service() {

while (true) {

Socket socket=null;

try {

socket = serverSocket.accept();

executorService.execute(new Handler(socket));

}catch (IOException e) {

e.printStackTrace();

}

}

}

public static void main(String args[])throws IOException {

new EchoServer().service();

}

}

/** 负责与单个客户通信的任务,代码与3.6.1节的例程3-5的Handler类相同 */

class Handler implements Runnable{…}

在EchoServer的构造方法中,调用Executors.newFixedThreadPool()创建了具有固定工作线程数目的线程池。在EchoServer的service()方法中,通过调用executor- Service.execute()方法,把与客户通信的任务交给了ExecutorService线程池来执行。

内容导航

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值