java服务器端口怎么用线程池写,Java 用线程池实现web服务器

今天在应用中用到了线程池,于是我就想web服务器肯定是用到了线程池,但是他们是怎样实现的呢?于是我就试着写了一个简单的模型

package httpserver;

import java.io.IOException;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Main {

public static void main(String[] args) {

new Main().startSystem();

}

void startSystem(){

//创建一个固定大小的线程池

ExecutorService service = Executors.newFixedThreadPool(100);

ServerSocket serverSocket = null;

try {

serverSocket = new ServerSocket(80);

Socket sock = null;

while((sock=serverSocket.accept()) != null){

//创建一个线程来处理请求

SocketHandleThread handleThread = new SocketHandleThread(sock);

//加入任务队列,等待执行

service.execute(handleThread);

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

class SocketHandleThread extends Thread{

Socket socket ;

public SocketHandleThread(Socket socket) {

this.socket = socket;

}

@Override

public void run() {

try {

OutputStream out = socket.getOutputStream();

out.write("hello, request handled".getBytes());

} catch (IOException e) {

e.printStackTrace();

// terminate the thread by returnning

}

}

}

这样的代码是能够处理请求,但是总觉的是有问题的,我的理解是线城市应该是先创建好n个线程,然后要用的时候从池中取一个,然后将某些参数传给该线程,然后就执行了。

但我这里是每次有请求来都创建一个线程,这样肯定是不行的,太好资源了,不知道到底要怎样搞,再慢慢想吧!大家如果知道,请不吝赐教!在下感激不尽。

============2015年7-28=============

通过网上的文章和自己 的一些思考,终于弄明白了线程池的使用以及我之前的错误是在哪里 ,现在正确的实现方法。

package httpserver;

import java.io.IOException;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.LinkedList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Main {

int workerThreadCount = 5;

WorkerThread [] workerThread = new WorkerThread[workerThreadCount];

LinkedList taskQueue = new LinkedList();

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

Main m = new Main();

m.startWorkerThreads();

m.startSystem();

}

void startWorkerThreads(){

for(int i = 0 ;i< workerThreadCount;i++){

workerThread[i] = new WorkerThread(taskQueue);

workerThread[i].start();

}

}

void startSystem(){

ExecutorService service = Executors.newFixedThreadPool(100);

ServerSocket serverSocket = null;

try {

serverSocket = new ServerSocket(8000);

Socket sock = null;

while((sock=serverSocket.accept()) != null){

//在向任务队列添加任务是需要同步,也就是要获取对象锁

synchronized (taskQueue){

SocketTask sockThread = new SocketTask(sock);

taskQueue.add(sockThread);

//唤醒一个等待中的worker线程来执行任务队列中的任务

taskQueue.notify();

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

//工作线程

class WorkerThread extends Thread{

LinkedList taskQueue;

public WorkerThread(LinkedList taskQueue) {

this.taskQueue = taskQueue;

}

public List getTaskQueue() {

return taskQueue;

}

public void setTaskQueue(LinkedList taskQueue) {

this.taskQueue = taskQueue;

}

@Override

public void run() {

while(true){

SocketTask task = null;

synchronized(taskQueue){

if(taskQueue.isEmpty()){

try {

taskQueue.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}else{

task = taskQueue.removeFirst();

}

}

if(task != null){

//直接调用run,并不是启动线程,只是执行了这个对象的run方法,和调用一个类的方法没区别

task.run();

}

}

}

}

//请注意这个类虽然继承了Thread,但是我们并不是把它作为一个线程来启动的,只是图方便使用了他的run方法,也可以自定义接口,JDK的 线程池也是这样搞的

class SocketTask extends Thread{

Socket socket ;

public SocketTask(Socket socket) {

this.socket = socket;

}

@Override

public void run() {

try {

OutputStream out = socket.getOutputStream();

out.write("hello, request handled , ^_^ ".getBytes());

out.flush();

out.close();

socket.close();

} catch (IOException e) {

e.printStackTrace();

// terminate the thread by returnning

}

}

}

之前主要的错误是,我以为线程池执行需要的Runnable是一个线程对象,其实不是,你也可以定义为其他的接口,线程在调用时其实是直接调用的run()方法,所以没有启动线程(只有调用start()方法才会启动线程)。

上面的代码时自己实现了一个 简单的echo server,每次有客户端连接时,向客户端打印一条信息,这里的线程池是自己实现的,这种方式虽然在一定程度上可以正常工作但还是缺少很多功能,可以使用JDK提供的线程池,具有更多的功能,比如拒绝服务 以及更完善的排队队列。

问题1:我有遇到了一个问题,当我在创建ServerSocket时指定了,80端口,这是我本机的apache服务器也在运行,但并没有报错,然后请求被发到了apache服务器,这是什么原因的?求解答哦

补充:关于问题1答案已经找到了,这个问题很值得关注,请参考我的这篇文章 关于ip 0.0.0.0

感谢这篇文章的作者:自己实现线程池

关于线程池详细的参考文章 线程池详细介绍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值