定义线程池的相关接口类,该实现只展示了线程池的基本工作原理,生命周期之类的功能没有添加
/*
*线程池接口,只定义了提交任务的方法,其他的相应方法可以自己添加
*/
package com.pool;
public interface ThreadPool {
public void execute(Job job);//提交任务
}
/*
*任务接口
*/
package com.pool;
public interface Job {
public void run() throws Exception;
}
/*线程池实现类*/
package com.pool;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class DefaultThreadPool implements ThreadPool {
private LinkedList<Job> jobs = new LinkedList<Job>();//任务列表
private List<Worker> workers = new ArrayList<Worker>();//工作线程列表
/*构造方法,构造wc个工作线程*/
public DefaultThreadPool(int wc){
for(int i=0; i< wc ;i++){
Worker w = new Worker();
workers.add(w);
Thread t = new Thread(w,"worker-" + i);
t.start();
}
}
@Override
public void execute(Job job) {
synchronized(jobs){
jobs.addLast(job);//添加任务到任务列表
jobs.notify();//通知等待任务的工作线程,有任务了
}
}
class Worker implements Runnable{
private boolean shutdown = false;
@Override
public void run() {
Job job = null;
while(!shutdown){//继续下一个任务直到关闭
synchronized(jobs){
while(jobs.isEmpty()){
try {
jobs.wait();//任务列表为空时,等待任务
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
job = jobs.removeFirst();//获取一个任务
}
try {
job.run();//执行任务
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
定义两个实际的工作任务,一个是发送文件到服务器,一个是接受从客户端接受文件
//从客户端接受文件并保存
package com.pool;
import java.io.FileOutputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class FileReceiverJob implements Job {
static InetSocketAddress local = new InetSocketAddress("localhost",9090);
SocketChannel sc;
ByteBuffer buf;
public FileReceiverJob(SocketChannel sc){
this.sc = sc;
}
@Override
public void run() throws Exception {
buf = ByteBuffer.allocate(10240);
readFile(sc,buf);//读取客户发送过来的文件并保存
sc.close();
}
private void readFile(SocketChannel sc, ByteBuffer buf)throws Exception{
boolean done = false;//文件名部分是否处理完毕
ByteBuffer name = ByteBuffer.allocate(1024);//用来保存文件名的部分
while(!done){
//获取文件名,第一个换行符之前的是文件名
sc.read(buf);
buf.flip();
char c = (char)buf.get();
while(c != '\n'){
name.put((byte)c);
if(buf.hasRemaining()){
c = (char)buf.get();
}else{
break;
}
}
if(c == '\n'){
done = true;
}else{
done = false;
buf.clear();
}
}
name.flip();
String filename = "";
while(name.hasRemaining()){
filename += (char)name.get();
}
System.out.println("[" + Thread.currentThread().getName() + "][" + filename + "]");
FileChannel fc = (new FileOutputStream(filename + ".ser")).getChannel();
for(int i=0; i<10; i++){
System.out.println("[" + Thread.currentThread().getName() + " is woring....]");
Thread.sleep(1000);//模拟长时间的任务执行时间
}
//至此,文件名获取完毕,接下来的内容是文件内容
while(buf.hasRemaining()){
// System.out.print((char)buf.get());
fc.write(buf);
}
buf.clear();
while((sc.read(buf))!=-1){
buf.flip();
while(buf.hasRemaining()){
// System.out.print((char)buf.get());
fc.write(buf);
}
buf.clear();
}
fc.close();
}
}
//发送文件到服务器的任务类
package com.pool;
import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
public class FileSenderJob implements Job {
private String filename = "e:/temp/big.txt";
static SocketAddress remote = new InetSocketAddress("localhost",9090);
public FileSenderJob(String name){
this.filename = name;
}
@Override
public void run() throws Exception{
System.out.println("[" + Thread.currentThread().getName() + "]send[" + filename + "]");
SocketChannel sc = SocketChannel.open();
sc.connect(remote);
ByteBuffer buf = ByteBuffer.allocate(102400);
//send the file name
// System.out.println("file name send:" + filename);
buf.put((filename+"\n").getBytes());
buf.flip();
while(buf.hasRemaining()){
sc.write(buf);
}
buf.clear();
//send the file content
// System.out.println("send file content");
FileChannel fic = (new FileInputStream(filename)).getChannel();
while(fic.read(buf)!=-1){
buf.flip();
while(buf.hasRemaining()){
sc.write(buf);
}
buf.clear();
}
fic.close();
sc.close();
}
}
//客户端实现
package com.client;
import java.io.File;
import com.pool.DefaultThreadPool;
import com.pool.FileSenderJob;
import com.pool.Job;
public class Client {
public static void main(String[] args) throws Exception{
File dir = new File("E:\\temp");
File[] fs = dir.listFiles();//列举目录下的所有文件
DefaultThreadPool cp = new DefaultThreadPool(4);
for(int i=0; i<fs.length; i++){
// System.out.println(fs[i].getCanonicalPath());
//每个文件创建一个发送任务并提交
Job job = new FileSenderJob(fs[i].getCanonicalPath());
cp.execute(job);
}
}
}
//服务器端实现类
package com.client;
import java.io.File;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import com.pool.DefaultThreadPool;
import com.pool.FileReceiverJob;
import com.pool.FileSenderJob;
import com.pool.Job;
public class Server {
static InetSocketAddress local = new InetSocketAddress("localhost",9090);
public static void main(String[] args) throws Exception{
DefaultThreadPool sp = new DefaultThreadPool(3);
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.bind(local);
while(true){
SocketChannel sc = ssc.accept();//接受客户连接
//接到连接后创建任务并提交
FileReceiverJob job = new FileReceiverJob(sc);
sp.execute(job);
}
}
}