一个简单的java线程池实现

定义线程池的相关接口类,该实现只展示了线程池的基本工作原理,生命周期之类的功能没有添加

/*
*线程池接口,只定义了提交任务的方法,其他的相应方法可以自己添加
*/
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);
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值