Java 阻塞线程服务器
2014-01-21 10:41
375 查看
代码下载:http://pan.baidu.com/s/1ntEyLML
下面是一个阻塞线程服务器的代码例子。
EchoServer
EchoServer类的构造方法负责创建线程池,启动服务器,把它绑定到一个本地端口。EchoServer类的service()方法负责接收客户的连接。每接收到一个客户连接,就把它交给线程来处理,线程池取出一个空闲的线程,来执行Handler对象的run()方法。Handler类的handler()方法负责与客户端通信。该方法先获得与SocketChannel关联的Socket对象,然后从Socket对象中得到输入流与输出流,再接收和发送数据。
下面是一个阻塞线程服务器的代码例子。
EchoServer
package block; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Handler; import java.util.logging.LogRecord; public class EchoServer { private int port = 8000; private ServerSocketChannel serverSocketChannel = null; private ExecutorService executorService; private static final int POOL_MULTIPLE = 4; public EchoServer() throws IOException { // 创建一个线程池 executorService = Executors.newFixedThreadPool(Runtime.getRuntime() .availableProcessors() * POOL_MULTIPLE); // 创建一个ServerSocketChannel对象 serverSocketChannel = ServerSocketChannel.open(); // 使得在同一个主机上关闭了服务器程序,紧接着再启动该服务器程序时,可以顺利绑定相同的端口。 serverSocketChannel.socket().setReuseAddress(true); // 把服务器进程与一个本地端口绑定 serverSocketChannel.socket().bind(new InetSocketAddress(port)); System.out.print("Service Start"); } public void service() { while (true) { SocketChannel socketChannel = null; try { socketChannel = serverSocketChannel.accept(); //处理客户连接 executorService.execute(new Handler(socketChannel)); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } } } public static void main(String args[]) throws IOException { new EchoServer().service(); } //处理客户连接 class Handler implements Runnable { private SocketChannel socketChannel; public Handler(SocketChannel socketChannel) { this.socketChannel = socketChannel; } @Override public void run() { // TODO Auto-generated method stub handle(socketChannel); } public void handle(SocketChannel socketChannel) { try { //获得与socketChannel关联的Socket对象 Socket socket = socketChannel.socket(); System.out.println("接收到客户连接,来自:" + socket.getInetAddress() + ":" + socket.getPort()); BufferedReader br = getReader(socket); PrintWriter pw = getWriter(socket); String msg = null; while ((msg = br.readLine()) != null) { System.out.println(msg); pw.println(echo(msg)); if (msg.equals("bye")) break; } } catch (IOException e) { // TODO: handle exception e.printStackTrace(); }finally{ try { if (socketChannel != null) socketChannel.close(); } catch (IOException e2) { // TODO: handle exception e2.printStackTrace(); } } } private PrintWriter getWriter(Socket socket) throws IOException { OutputStream socketOut = socket.getOutputStream(); return new PrintWriter(socketOut,true); } private BufferedReader getReader(Socket socket) throws IOException { InputStream socketIn = socket.getInputStream(); return new BufferedReader(new InputStreamReader(socketIn)); } public String echo(String msg) { return "echo:" + msg; } } }
EchoServer类的构造方法负责创建线程池,启动服务器,把它绑定到一个本地端口。EchoServer类的service()方法负责接收客户的连接。每接收到一个客户连接,就把它交给线程来处理,线程池取出一个空闲的线程,来执行Handler对象的run()方法。Handler类的handler()方法负责与客户端通信。该方法先获得与SocketChannel关联的Socket对象,然后从Socket对象中得到输入流与输出流,再接收和发送数据。
相关文章推荐
- Java线程(十三):BlockingQueue-线程的阻塞队列
- Java线程阻塞与中断
- Java 使用线程经验之阻塞队列
- java 线程的阻塞 暂停 启用
- Java线程:新特征-阻塞栈
- 12-使用java5条件阻塞condition实现线程间通信-实现线程间通信方式(2)
- java中线程阻塞之sleep、suspend、join、wait、resume、notify方法解析(一)
- java使用阻塞队列(BlockingQueue)来控制线程通信
- 初见Java多线程(三、线程的阻塞状态)
- Java线程阻塞
- JAVA学习笔记50——线程状态+停止进程+阻塞进程
- Java线程:新特征-阻塞栈 - 熔 岩 - 51CTO技术博客
- Swing 刷新组件java swing中两大原则: 1. 不要阻塞UI线程 2. 不要在UI线程外的线程去操作UI控件
- java线程阻塞唤醒的四种方式
- JAVA进阶6.5——线程的让步与阻塞
- Java服务器线程查看和线程优化
- Java -- 使用阻塞队列(BlockingQueue)控制线程通信
- java线程阻塞中断与LockSupport使用介绍
- Java线程阻塞
- Java线程的阻塞,就绪和执行