线程池

[size=medium][b]为什么使用线程池?[/b][/size]
[size=medium]为了减少瞬间峰值问题,服务器一般都使用线程池,规定了同时并发的最大数量,避免了线程的无限增长.[/size]

在浏览器里输出 http://127.0.0.1:8888/
就可以出结果了

[size=medium]Main.java[/size]

package com.apq.threadpool;

import com.apq.server.MiniServer;

public class Main {

public static void main(String[] args) {
new EchoServer(8888, 1000).service();
}
}


[size=medium]EchoServer.java[/size]

package com.apq.threadpool;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class EchoServer {
//监听的端口号
private final int port;

//单个cpu工作线程数量
private final int poolSize;

private ServerSocket serverSocket;

//线程池
private ThreadPool threadPool;

//jdk线程池
private ExecutorService executorService;

public EchoServer(int port, int poolSize) {
this.port = port;
this.poolSize = poolSize;
//this.threadPool = new ThreadPool(Runtime.getRuntime().availableProcessors() * poolSize);
this.executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * poolSize);
}

//负责为每个客户分配一个线程
public void service() {
try {
serverSocket = new ServerSocket(port);
echo("Listening on " + serverSocket);
while(true) {
echo("Accepting...");
Socket clientSocket = serverSocket.accept();
echo("Connected to " + clientSocket);
//创建一个工作线程并启动(没有线程池的)
//new Thread(new Handler(clientSocket)).start();

//由线程池来处理客户通信
//this.threadPool.putHandler(new Handler(clientSocket));

//用jdk自带的线程池来处理客户通信
this.executorService.execute(new Handler(clientSocket));
}
} catch (IOException e) {
System.err.println(e);
}
}

private void echo(String msg) {
System.out.println(msg);
}
}


[size=medium]ThreadPool.java[/size]

package com.apq.threadpool;

import java.util.*;

public class ThreadPool extends ThreadGroup {
private static final int MAX_HANDLER = 100;
// 线程数量
private int poolSize;

// 工作队列
private static LinkedList<Runnable> workQueue;

// 线程池ID
private static int threadPoolID;

// 工作线程ID
private int workThreadPoolID;

private int count;

// 构造函数
public ThreadPool(int poolSize) {
super("ThreadPool-" + (threadPoolID++));
this.poolSize = poolSize;
this.count = 0;
workQueue = new LinkedList<Runnable>();
startWorks();
System.out.println("The EchoServer has started.");
}

// 创建并启动工作线程
private void startWorks() {
for (int i = 0; i < this.poolSize; i++) {
new WorkThread().start();
}
}

// 向工作队列加入一个新任务,由工作线程执行该任务
public synchronized void putHandler(Runnable handler) {
while (count >= MAX_HANDLER) {
try {
wait();
} catch (InterruptedException e) {
}
}
workQueue.add(handler);
count++;
notifyAll();
}

// 从工作队列中取出一个任务,工作线程会调用此方法
public synchronized Runnable getHandler() {
while (count <= 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
Runnable handler = workQueue.removeFirst();
count--;
notifyAll();
return handler;
}

// 内部类 工作线程
private class WorkThread extends Thread {
public WorkThread() {
}

@Override
public void run() {
while (!isInterrupted()) {
Runnable handler = getHandler();
if (handler != null)
handler.run();
}
}
}
}



[size=medium]Handler.java[/size]

package com.apq.threadpool;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

//负责与单个客户的通信
public class Handler implements Runnable {
private Socket clientSocket;

public Handler(Socket clientSocket) {
this.clientSocket = clientSocket;
}

@Override
public void run() {
try {
DataOutputStream out = new DataOutputStream(clientSocket
.getOutputStream());
out.writeBytes("HTTP/1.1 200 OK\r\n");
out.writeBytes("Content-type: text/html\r\n");
out.writeBytes("\r\n");

out.writeBytes("<html><head></head><body>");
out.writeBytes("<p>" + "new connection accepted!<br>"
+ clientSocket.getInetAddress() + ":"
+ clientSocket.getPort() + "</p>");
out.writeBytes("</body></html>");
} catch (IOException e) {
//record log
} finally {
if (clientSocket != null)
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值