要求是打印用户输入的字符串,用户输入一个字符串就创建一个线程去打印他,用户不断输入,就不断创建,当池中线程数量达到池的容量后提示用户池满了,请等等。
解决方案 »
- java windows7 MSSQL
- 如何写入在文件的指定行处?
- 关于用StringTokenizer类的一个循环出现的小问题
- 哪位用过officelnfs的LookAndFeel,字体怎么改?
- 新手:GregorianCalendar同Calendar有什么不同啊,一般情况下应该用哪个啊?
- Object和Color类型之间怎么转换?
- java 泛型函数需要返回Integer 我返回null 为什么报空指针异常
- 怎样使一个JFrame不能被最大化?
- 再问有关JDBC驱动的配置问题。
- 我如此的实例化FILER组件有什么错误,请执教!
- java 导入文件路径时记住以前的路径
- JAVA SE 基础问题!
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Date;
import java.util.Vector;public class Handler extends Thread {
private Vector<Socket> taskQueue;
public Handler(Vector<Socket> taskQueue,String threadName) {
super(threadName);
this.taskQueue = taskQueue;
}
@Override
public void run() {
/*
* 这里使用一个死循环,保证线程完成它所分配的任务后
* 继续回到线程池中等待分配新的任务
* 从而实现线程重利用
*/
while(true){
Socket socket = null;
synchronized(taskQueue){
/*
* 如果没有排列等候的任务,所有线程一直等待
*/
while(taskQueue.isEmpty()){
try {
/*
* 一个对象调用它的wait()方法时,它会首先释放它的锁
* 然后导致当前线程等待
* 这个时候,等待taskQueue对象的锁
* 的线程会得到锁,进入同步块,运行到这里时,该线程也释放锁,等待。。
* 直到另外一个线程,调用taskQueue.notifyAll()方法,
* 所有在这里等待的线程,就会让taskQueue试着去得到它的锁,
* 如果得到了锁,才会往下执行。否则一直等待。
*/
taskQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*
* 任务队列中出现任务,弹出尾部的任务,保证先进先出顺序
*/
socket = taskQueue.remove(taskQueue.size()-1);
}
try {
InputStream in = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String strline = null;
while((strline=reader.readLine())!=null){
System.out.println(Thread.currentThread().getName()+" 处理了请求 "+strline);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}Server.javaimport java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;public class Server {
private static final int PORT = 9999;
public static void main(String[] args) {
/*使用Vector实现任务队列,
*因为它是同步的,而且是一种线性的数据结构,
*实现队列非常方便
* */
Vector<Socket> taskQueue = new Vector<Socket>();
/*
* 在服务器启动的时候就去启动 线程池中的线程
* 让它们去等待分配任务
*/
Handler[] handlers = new Handler[5];
for(int i=0;i<handlers.length;i++){
handlers[i] = new Handler(taskQueue,"线程"+i);
System.out.println("线程"+i+" start...");
handlers[i].start();
}
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while(true){
Socket socket = serverSocket.accept();
/*
* 注意,wait(),notify(),notifyAll()方法都需要放在同步块当中
* 因为一个对象调用它的这些方法,首先要得到对象的锁
*/
synchronized(taskQueue){
/*
* 将任务放在集合的头部
* 在线程中取出时,弹出是的尾部的任务
* 这样保证先进先出的任务队列
* */
taskQueue.add(0,socket);
/*
* 通知线程池中等待taskQueue对象的锁的所有线程
*/
taskQueue.notifyAll();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}}
Client.javaimport java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.UUID;public class Client {
public static void main(String[] args) {
/*
* 和服务器连接五十次,模拟多客户请求
*/
for(int i=0;i<50;i++){
try {
Socket socket = new Socket("127.0.0.1",9999);
OutputStream output = socket.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
writer.write(UUID.randomUUID().toString());
writer.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}}
看楼主头像,我只想对lz说,少打一会dota或者wow研究一下,就什么都明白了。
线程池基本上是这样实现的:1:先 new 出固定数量的 Thread,类似于这样:Thread t0 = new Thread(new WorkRunnable());WorkRunnable 的结构基本上是这样的(实际远远比这复杂):public class WorkRunnable implements Runnable { private Runnable command; public WorkRunnable(Runnable command) {
this.command = command;
} public void run() {
command.run();
} public void setCommand(Runnable command) {
this.command = command;
}
}2:执行 t0.start() 可以执行线程,如果执行完了,将 WorkRunnable 中的 command 换一个再 start() 又可以执行了。基本上的思路就是这样,但是实现起来极其复杂,不建议自己写,了解一下就可以了。
public static void main(String[] args) {
int threadMax = 5;
ThreadPoolExecutor executor =
new ThreadPoolExecutor(2,threadMax,3,TimeUnit.SECONDS, new ArrayBlockingQueue(3),new ThreadPoolExecutor.CallerRunsPolicy());
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("请输入:");
final String s = sc.nextLine();
if(threadMax == executor.getActiveCount()){
System.out.println("线程满请稍后输入数据");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else{
executor.execute(new Runnable(){
public void run(){
try {
Thread.sleep(5000);
System.out.println("s:" + s);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}