`

带线程池的小服务器-Java实现

阅读更多

前两天,利用线程池技术(ThreadPool)写了个web服务器,其性能当然无法和apache iis等相比,但基本的功能都有了,唯一欠缺的是无法解析动态页面,采用解释执行(asp模式的)效率太低,如果采用编译执行,要么自己编写一个编译器来编译整个动态页面,要么采用预编译,很复杂。。。。

现在把代码拿出来晒一晒!由于只是初步的设计所以没有考虑到很多设计模式,代码在优化上很不到位,请各位高手不吝赐教。

MainServer.java 这是主服务文件,也是提供主线程的类,主线程将请求分发给其他业务线程(workerthread)出来

package com.threadpool;

import java.net.ServerSocket;

public class MainServer
{
 
 public static int clientCount = 0;
 
 //ThreadPool threadPool = null;
 int port;
 PoolManager poolm;
 public MainServer(int port)
 {
  poolm=PoolManager.getInstance();
  poolm.creatThreadPool(100, ActionWorker.class);
  this.port = port;
 }
 public void start() throws Exception
 {
  ServerSocket ss = new ServerSocket(port);
  System.out.println("MainServer is starting.....");
  
  while(true)
  {
   clientCount++;
   poolm.doService(ss.accept());
   System.out.println(clientCount+"connections");
  }
 }
 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception
 {
  // TODO Auto-generated method stub
  MainServer server = new MainServer(80);
  server.start();
 }
 
}

PoolManager.java 线程池管理器,该类负责管理线程池,如创建新线程,回收线程等等。
package com.threadpool;

import java.net.Socket;

import Pool.ThreadWorker;

public class PoolManager
{
 //singleton pattern
 private static PoolManager instance = null;
 ThreadPool threadPool = null;
 private PoolManager()
 {
  
 }
 
 public synchronized static PoolManager getInstance()
 {
  if(instance == null)
   instance = new PoolManager();
  
  return instance;
 }
 
 //create thread pool
 public void creatThreadPool(int max, Class<ActionWorker> worker)
 {
  
  try
  {
   threadPool = new ThreadPool(max, worker);
   System.out.println("create a threadpool...");
  }
  catch (Exception e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
 private WorkerThread getWorker() throws Exception
 {  
    return threadPool.getWorker();  
 }
 
 public void doService(Object o)
 {  
  try
  {
   getWorker().wake((Socket)o);
   System.out.println(Thread.currentThread().getName());
  }
  catch (Exception e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }  
 }
}

WorkerThread.java 业务线程类,负责处理具体的请求。

package com.threadpool;

import java.net.Socket;

public class WorkerThread extends Thread
{
 
  private IWorker worker;
  private Socket data;
  private ThreadPool pool;
  WorkerThread(String id, IWorker worker, ThreadPool pool)
  {
   super(id);
   this.worker = worker;
   this.pool = pool;
   this.data = null;
  }
  
  public synchronized void wake(Socket data)
  {
   this.data = data;
   System.out.println("wake up..." + Thread.currentThread().getName());
   notify();
  }
  
  public synchronized void run()
  {
   //boolean stop = false;
   System.out.println("run....");
   while(true)
   {
    if(data == null)
    {
     try
     {
      wait();
      System.out.println(Thread.currentThread().getName()+"wait...");
     }
     catch (InterruptedException e)
     {
      // TODO Auto-generated catch block
      e.printStackTrace();
      continue;
     }
    }
    
    System.out.println(this.getName()+"are working"+Thread.currentThread().getName());
    worker.run(data);
    data = null;
    if(!pool.pushBack(this))
     break;
  }
  
 }
}

IWorker.java为业务逻辑接口

package com.threadpool;

public interface IWorker
{
 public void run(Object data);
}

ActionWorker.java真正干活的那个类,称为业务逻辑类,与j2ee中的javaBean对应。

package com.threadpool;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class ActionWorker implements IWorker
{
 
 public void run(Object data)
 {
  handleRequest((Socket)data);
  
 }
 
 private void handleRequest(Socket s)
 {
  try
  {
   InputStream is = s.getInputStream();
   OutputStream os = s.getOutputStream();
   Request request = new Request(is);
   request.parse();
//   // create Response object
   Response response = new Response(os);
      response.setRequest(request);
      response.sendStaticResource();
   System.out.println("worker is working..");
   MainServer.clientCount--;
   //执行完毕后关闭socket,释放线程
   s.close();
  }
  catch(IOException ex)
  {
   ex.printStackTrace();
  }
  
 }
}

Requset.java封装请求的类,主要用于提取被请求的文件

package com.threadpool;

import java.io.IOException;
import java.io.InputStream;

public class Request
{
 private InputStream input;
 private String uri;

   public Request(InputStream input)
   {
     this.input = input;
   }
   //从请求中解析出文件名
 public void parse()
 {
  StringBuffer request = new StringBuffer(2048);
     int len;
     byte[] buffer = new byte[2048];
     try
     {
       len = input.read(buffer);
     }
     catch (IOException e)
     {
       e.printStackTrace();
       len = -1;
     }
     for (int i=0; i<len; i++)
     {
       request.append((char) buffer[i]);
     }
     System.out.print(request.toString());
     uri = parseUri(request.toString());
   }
 //截取请求的文件名
   private String parseUri(String requestString)
   {
     int index1, index2;
     index1 = requestString.indexOf(' ');
     if (index1 != -1)
     {
       index2 = requestString.indexOf(' ', index1 + 1);
       if (index2 > index1)
         return requestString.substring(index1 + 1, index2);
     }
     return null;
   }

   public String getUri()
   {
     return uri;
   }
}

Response.java 封装相应流的类

package com.threadpool;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Response
{
 private static final int BUFFER_SIZE = 1024;
   public Request request;
   public OutputStream output;

   public Response(OutputStream output)
   {
     this.output = output;
   }

   public void setRequest(Request request)
   {
     this.request = request;
   }

   public void sendStaticResource() throws IOException
   {
     byte[] bytes = new byte[BUFFER_SIZE];
     FileInputStream fis = null;
     try
     {
        File file = new File(System.getProperty("user.dir")+File.separator+"webroot", request.getUri());
        if (file.exists())
        {
          fis = new FileInputStream(file);
          int ch = fis.read(bytes, 0, BUFFER_SIZE);
          while (ch!=-1)
          {
             output.write(bytes, 0, ch);
             ch = fis.read(bytes, 0, BUFFER_SIZE);
          }
        }
        else
        {
          // file not found
          String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
            "Content-Type: text/html\r\n" +
            "Content-Length: 23\r\n" +
            "\r\n" +
            "<h1>File Not Found</h1>";
          output.write(errorMessage.getBytes());
        }
     }
     catch (Exception e)
     {
        // thrown if cannot instantiate a File object
        System.out.println(e.toString() );
     }
     finally
     {
        if (fis!=null)
         fis.close();
     }
   }
}

在class文件夹下建立 webroot文件夹作为网站的根目录,把网页文件放在下面就可以通过 http://localhost/yourfilename 访问了,简单的服务器就写出来了,由于使用了池技术所以其原理更接近于真正的webserver.

 

ps: apache服务器是用纯c编写的,其实现的复杂程度的确让人难以想象。

分享到:
评论

相关推荐

    简单JAVA线程池应用---服务器端

    此文档是: 基于简单线程池概念的JAVA服务器端应用 附有连接ORACLE数据库等简单操作. 操作描述:  服务器启动后,会启动10个子线程运行.(配合客户端10个请求进行模拟,控制台输出模拟过程) 服务器主程序进入一个有...

    线程池与工作队列--Java 理论与实践

    ### 线程池与工作队列:Java理论与实践 #### 一、线程池的概念及重要性 线程池是一种广泛应用于服务器应用程序的技术,主要用于优化资源利用效率,提高程序响应速度,并确保系统的稳定性和可靠性。在多线程编程...

    Java线程池学习资料-全

    在Java中,线程池的实现主要依赖于`java.util.concurrent`包下的`ThreadPoolExecutor`类。 线程池的运行原理在于,当一个任务被提交到线程池时,线程池首先会检查当前是否还有空闲的工作线程。如果有,那么任务会被...

    线程池 和队列-Brian Goetz

    在Java等编程语言中,已经提供了内置的线程池实现,如Java的Executor框架,它提供了一种便捷的方式来创建和管理线程池。通过这些高级抽象,开发者可以更加专注于业务逻辑的实现,而不必从零开始编写线程池的代码。 ...

    Spring Boot整合FTPClient线程池的实现示例

    Spring Boot 整合 FTPClient 线程池的实现示例 在本文中,我们将探讨如何在 Spring Boot 项目中整合 FTPClient 线程池的实现示例。FTPClient 是一个常用的 FTP 客户端库,而线程池则可以帮助我们减少频繁创建和销毁...

    线程池java

    在Java中,`ThreadPoolExecutor`是线程池的核心实现类之一,它提供了丰富的配置选项来满足不同的应用场景需求。该类继承自`AbstractExecutorService`,实现了线程池的主要功能。 **构造方法详解**: ```java ...

    简单线程池与线程池检查的实现

    在标签“源码”和“工具”的提示下,我们可以推测该话题可能涉及到线程池的具体实现代码,例如使用Java的`java.util.concurrent.ThreadPoolExecutor`类进行线程池的创建和管理,以及可能通过自定义工具或框架对...

    JAVA线程池的原理与实现.pdf

    Java线程池是一种高效利用系统资源、管理并发执行任务的机制。...总的来说,理解Java线程池的工作原理和实现对于优化并发应用程序至关重要,它可以帮助我们更好地控制系统的并发度,提高系统的响应速度和资源利用率。

    基于Java线程池技术的数据爬虫设计与实现.pdf

    本文所提及的基于Java线程池技术的数据爬虫设计与实现,不仅涉及到了数据爬虫的原理和架构,还包括了多线程编程的知识点,以及线程池技术在数据爬虫中的具体应用。 首先,数据爬虫的基本原理是模拟用户的点击行为,...

    java线程池实例详细讲解

    例如,在高并发的Web服务器中,我们可能希望设置较小的`corePoolSize`以减少资源消耗,较大的`maximumPoolSize`来应对瞬间的请求高峰,并使用有限大小的队列避免无限制的缓冲任务。 在实际开发中,我们还需要关注...

    java服务器端Socket线程池

    综上所述,Java服务器端的Socket线程池是实现高效并发处理的关键技术,通过合理的线程管理和资源调度,能够显著提升服务器的处理能力,并保证服务的稳定性和可靠性。在实际开发中,应结合具体需求选择合适的线程池...

    Java实现的线程池、消息队列功能

    本文将基于给定的标题“Java实现的线程池、消息队列功能”来详细阐述这两个概念及其在Java中的实现。 首先,我们来讨论线程池。线程池是一种多线程处理形式,预先创建了一定数量的线程,它们存储在池中等待任务。当...

    JAVA服务器端应用Socket线程池

    本文将通过分析一个具体的Java服务器端应用程序中的Socket线程池实现,探讨线程池的设计思路及其在Socket通信中的应用。 #### 二、Socket线程池的基本概念 Socket通信是网络编程中常用的一种技术,它允许不同...

    java常用工具类封装

    Java中的线程池是由`java.util.concurrent`包中的`ExecutorService`接口及其实现类如`ThreadPoolExecutor`提供的。线程池可以有效地管理和控制并发执行的任务数量,避免频繁创建和销毁线程带来的性能开销。通过设置...

    <邮件自动发送>例子-Java实现

    本示例将探讨如何使用Java实现邮件自动发送功能。通过Java编程,我们可以利用SMTP(Simple Mail Transfer Protocol)协议与邮件服务器进行交互,从而完成邮件的发送。 首先,我们需要导入JavaMail API库,它提供了...

    JAVA服务器端Socket线程池

    本文将详细解析标题为“JAVA服务器端Socket线程池”的知识点,涵盖其基本概念、实现原理、核心类与方法的介绍,并结合示例代码深入探讨其实现细节。 #### 二、Socket编程基础 Socket编程是网络通信的基础,通过...

    Java线程池使用说明

    Java线程池是Java并发编程中的重要组件,它能够有效地管理和复用线程,从而提高程序的执行效率和降低资源消耗。在JDK 1.5版本之前,Java对线程池的支持非常有限,而在JDK 1.5之后,加入了java.util.concurrent包,...

    Java实现的Http服务器

    本项目是用Java语言实现的一个简单的HTTP服务器,同时也包含了一个客户端,让我们一起深入探讨其中的关键知识点。 首先,我们关注的是Java语言在实现HTTP服务器中的应用。Java SE(标准版)提供了丰富的API,使得...

    mysql-connector-java-8.0.11

    1. **添加依赖**:将mysql-connector-java-8.0.11.jar添加到项目的类路径中,或者在Maven/Gradle等构建工具中配置相应的依赖。 2. **建立连接**:使用`DriverManager.getConnection()`方法,传递数据库URL、用户名...

    java聊天室,利用线程池实现多用户聊天室

    Java聊天室是一个典型的多用户实时交互系统,它利用了Java的网络编程能力以及并发处理机制,特别是线程池技术,来实现多个用户之间的同步通信。在这个项目中,我们将深入探讨如何构建这样一个聊天室,以及线程池在...

Global site tag (gtag.js) - Google Analytics