http://blog.csdn.net/github_26672553/article/details/77507797
前面我们了解了socket
的概念,并且最后还用来模拟一个http协议。
之前我们的代码还是单线程的,也就是我们是socket服务是单线程的。
我们前面学习ArrayList
的是也了解过线程的概念,还演示了ArrayList的线程不安全问题。
文章地址:
http://blog.csdn.net/github_26672553/article/details/77164120
1、我们知道要多线程可以直接new Thread()
,也可以新建一个类,该类实现Runnable
接口。我们这里新建一个类HttpThread.java:
public class HttpThread implements Runnable {
private ServerSocket serverSocket;
public HttpThread(ServerSocket serverSocket){
this.serverSocket = serverSocket;
}
@Override
public void run() {
try {
Socket socket = this.serverSocket.accept();
// 要想获取客户端发送过来的内容,就要得到 InputStream类 的输入流对象
InputStream inputStream = socket.getInputStream();
// 要想给客户端发送数据,就要得到
OutputStream outputStream = socket.getOutputStream();
//==========使用我们自定义的http处理的相关类===========//
Request request = new Request(inputStream);
Response response = new Response(outputStream);
response.writePage(request.getPath());
// 关闭
inputStream.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码分享:构造函数里接受一个外部实例化后的ServerSocket对象
,run()
方法需要实现我们的业务。
ServerSocket serverSocket = new ServerSocket(9000);
Thread thread = new Thread(new HttpThread(serverSocket));
thread.start();
Thread thread1 = new Thread(new HttpThread(serverSocket));
thread1.start();
这样就开启了2个线程(是socket服务的线程)
2、但是这样并不能完事儿,因为到目前为止,我们的代码会自动断掉服务。也就是当你在浏览器建立一个连接之后 再新款窗口新建第二个连接时,会发现连接失败
。
接触 concurrent
是java5之后的一个多线程、并发工具包,有了它可以比较方便。
今天我们学习 concurrent的执行,涉及到的API如下:
Executors 是一个工厂类。用于创建线程池。
newCachedThreadPool 不定长 可回收空闲线程和新建;
newFixedThreadPool 定长线程池,超出线程需要等待;
newScheduledThreadPool 创建一个定长线程池,可进行周期性任务执行;
newSingleThreadExecutor 创建一个单线程化的线程池
这样我们socket服务端代码如下:
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9000);
ExecutorService executorService = Executors.newFixedThreadPool(2); //这是规定只能创建2个线程
executorService.execute(new HttpThread(serverSocket));
executorService.execute(new HttpThread(serverSocket));
}