当前页面: 开发资料首页 → Java 专题 → 菜鸟初学Java的备忘录(九)
摘要: 菜鸟初学Java的备忘录(九)
import java.io.*;可以看出,这个类与多线程Socket那一天的ConnectionHandler非常相似,但不同的是,它带有处理连接池的手段.
import java.net.*;
import java.util.*;
public class PooledRemoteFileServer {
protected int maxConnections;//定义能同时处理的客户机连接的最大数目 protected int listenPort;//定义要监听的端口号
protected ServerSocket serverSocket;
public PooledRemoteFileServer(int aListenPort, int maxConnections) {
listenPort = aListenPort;
this.maxConnections = maxConnections;
}
public static void main(String[] args) {
}
public void setUpHandlers(){//创建数目为maxConnections的 PooledConnectionHandler
}
public void acceptConnections(){//在 ServerSocket 上监听传入的客户机连接,和前面的RemoteFileServer,MultiThreadRemoteFileServer中的监听程序完全一样
}
protected void handleConnection(Socket incomingConnection) {
}//连接处理程序
}
同样,首先来看main函数
public static void main(String[] args) {
PooledRemoteFileServer server = new PooledRemoteFileServer(3000, 3);
server.setUpHandlers();//同前面所有服务器的main函数不同,我们先要创建一个连接池,这个池里面有三个可用的connectionHandler
server.acceptConnections();//一旦就绪,就开始监听
下面我们就来看创建三个connectionHandler的程序如何实现:
public void setUpHandlers(){
for (int i = 0; i < maxConnections; i++) {
PooledConnectionHandler currentHandler = new PooledConnectionHandler();
new Thread(currentHandler, "Handler " + i).start();
}
}
setUpHandlers() 方法创建maxConnections个PooledConnectionHandler并在新 Thread 中激活它们. PooledConnectionHandler在这里是一个用接口(Runnable)实现的线程体.用实现了Runnable的对象来创建Thread使我们可以在 Thread 调用 start() 并且可以期望在Runnable上调用了 run()。也就是说,我们的 PooledConnectionHandler 将等着处理进入的连接,每个都在它自己的Thread中进行。我们在示例中只创建三个Thread,而且一旦服务器运行,这就不能被改变。
acceptConnections()方法这里就略去不写了,看看连接处理程序handleConnection(Socket incomingConnection)
protected void handleConnection(Socket connectionToHandle) {
PooledConnectionHandler.processRequest(connectionToHandle);
}
这里连接处理程序直接调用了PooledConnectionHandler线程类的类方法processRequest对监听到的连接进行处理,显然这个processRequest是一个静态方法.
PooledRemoteFileServer类中的方法均涉及到一个重要的线程类,PooledConnectionHandler.下面就看看这样一个用接口实现的类长什么样:
public class PooledConnectionHandler implements Runnable {
protected Socket connection;//代表当前正在处理的Socket
protected static List pool = new LinkedList();//名为 pool 的静态 LinkedList 保存需被处理的连接,也就是用LinkedList来模拟一个连接池
public PooledConnectionHandler() {//构造函数
}
public void handleConnection() {//对连接的I/O操作在这里了
}
public static void processRequest(Socket requestToHandle) {//处理客户连接,将他们加入连接池
}
public void run() {//等待有连接来,来了,就调handleConnection()处理
}
}
public static void processRequest(Socket requestToHandle) {
synchronized (pool) {
pool.add(pool.size(), requestToHandle);
pool.notifyAll();
}
}
public void run() {这个函数告诉了我们每个PooledConnectionHandler线程主要都在run些什么.显然,它是要不停的去看连接池中有没有接入的连接,如果有,马上处理,因此它在等待"连接池有连接了"这样一个条件.那么谁来告诉它这个条件满足了呢,显然是刚才的processRequest.当processRequest发出通知(pool.notify())的时候,这个条件就满足了,这时run()中的处理程序就不用再继续等待了,就可以马上去出一个连接进行处理.反过来说,在这个条件没有满足之前,wait()所在的线程还是要处于阻塞状态,或者是说停滞状态.由于同样要对pool进行操作,所以这里也需要使用到同步块.
while (true) {
synchronized (pool) {
while (pool.isEmpty()) {
try {
pool.wait();
} catch (InterruptedException e) {return;}
}
connection = (Socket) pool.remove(0);//攫取池中的第一个连接,使之成为马上就要处理的connection
}
handleConnection();//然后交给handleConnection处理
}
}
import java.io.*;Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
import java.net.*;
import java.util.*;
public class PooledRemoteFileServer {
protected int maxConnections;
protected int listenPort;
protected ServerSocket serverSocket;
public PooledRemoteFileServer(int aListenPort, int maxConnections) {
listenPort = aListenPort;
this.maxConnections = maxConnections;
}
public void acceptConnections() {
try {
ServerSocket server = new ServerSocket(listenPort, 5);
Socket incomingConnection = null;
while (true) {
incomingConnection = server.accept();
handleConnection(incomingConnection);
}
} catch (BindException e) {
System.out.println("Unable to bind to port " + listenPort);
} catch (IOException e) {
System.out.println("Unable to instantiate a ServerSocket on port: " + listenPort);
}
}
protected void handleConnection(Socket connectionToHandle) {
PooledConnectionHandler.processRequest(connectionToHandle);
}
public static void main(String[] args) {
PooledRemoteFileServer server = new PooledRemoteFileServer(3000, 3);
server.setUpHandlers();
server.acceptConnections();
}
public void setUpHandlers() {
for (int i = 0; i < maxConnections; i++) {
PooledConnectionHandler currentHandler = new PooledConnectionHandler();
new Thread(currentHandler, "Handler " + i).start();
}
}
}
class PooledConnectionHandler implements Runnable {
protected Socket connection;
protected static List pool = new LinkedList();
public PooledConnectionHandler() {
}
public void handleConnection() {
try {
PrintWriter streamWriter = new PrintWriter(connection.getOutputStream());
BufferedReader streamReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String fileToRead = streamReader.readLine();
BufferedReader fileReader = new BufferedReader(new FileReader(fileToRead));
String line = null;
while ((line = fileReader.readLine()) != null)
streamWriter.println(line);
fileReader.close();
streamWriter.close();
streamReader.close();
} catch (FileNotFoundException e) {
System.out.println("Could not find requested file on the server.");
} catch (IOException e) {
System.out.println("Error handling a client: " + e);
}
}
public static void processRequest(Socket requestToHandle) {
synchronized (pool) {
pool.add(pool.size(), requestToHandle);
pool.notifyAll();
}
}
public void run() {
while (true) {
synchronized (pool) {
while (pool.isEmpty()) {
try {
pool.wait();
} catch (InterruptedException e) {
return;
}
}
connection = (Socket) pool.remove(0);
}
handleConnection();
}
}
}