Java 服务器套接字读取文件:无法处理BlockingQueue中的记录

Java 服务器套接字读取文件:无法处理BlockingQueue中的记录,java,multithreading,sockets,blockingqueue,Java,Multithreading,Sockets,Blockingqueue,我正在尝试将文本文件从客户端发送到套接字服务器。在顺序操作中使用单个线程读取文本文件。我正在使用BlockingQueue放置读取操作的记录,并尝试使用多线程机制处理这些记录。如果没有套接字通信(即,直接读取文件),则此代码可以很好地工作 客户端代码: try{ Socket socket = new Socket(hostName, PORTNUMBER); File file = new File(filePath);

我正在尝试将文本文件从客户端发送到套接字服务器。在顺序操作中使用单个线程读取文本文件。我正在使用BlockingQueue放置读取操作的记录,并尝试使用多线程机制处理这些记录。如果没有套接字通信(即,直接读取文件),则此代码可以很好地工作

客户端代码:

        try{
            Socket socket = new Socket(hostName, PORTNUMBER);
            File file = new File(filePath);

            byte[] bytes = new byte[16 * 1024];
            InputStream in = new FileInputStream(file);
            OutputStream out = socket.getOutputStream();

            int count;
            while ((count = in.read(bytes)) > 0) {
                out.write(bytes, 0, count);
            }

            out.close();
            in.close();
            socket.close();
        }catch(UnknownHostException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }
服务器代码:

public static final Map<Integer, Account> _resultMap= new ConcurrentHashMap<Integer, Account>();

public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
    while(true){
            if(mode.equals("deamon")){
                ServerSocket serverSocket = null;

                try {
                    serverSocket = new ServerSocket(8888);
                } catch (IOException ex) {
                    System.out.println("Unable to start up server on port 8888");
                }

               Socket socket = null;

                try {
                    socket = serverSocket.accept();
                } catch (IOException ex) {
                    System.out.println("Unable to accept client connection");
                }


                final int threadCount = 8;
                final BlockingQueue<String> queue = new LinkedBlockingQueue<String>(200);


                ExecutorService service = Executors.newFixedThreadPool(threadCount);
                for (int i = 0; i < (threadCount - 1); i++) {
                    service.submit(new CalcTask(queue));
                }
                service.submit(new ReadFileTask(queue, socket)).get();
                System.out.println(queue.size()); // Can see the count here

                service.shutdownNow();
                service.awaitTermination(365, TimeUnit.DAYS);


                for (Map.Entry<Integer, String> e : Map.entrySet()) {
                    System.out.println(e.getKey());
                }

                socket.close();
                serverSocket.close();
            }
    }
publicstaticfinalmap\u resultMap=newconcurrenthashmap();
公共静态void main(字符串[]args)引发IOException、InterruptedException、ExecutionException{
while(true){
if(模式等于(“deamon”)){
ServerSocket ServerSocket=null;
试一试{
serverSocket=新的serverSocket(8888);
}捕获(IOEX异常){
System.out.println(“无法在端口8888上启动服务器”);
}
套接字=空;
试一试{
socket=serverSocket.accept();
}捕获(IOEX异常){
System.out.println(“无法接受客户端连接”);
}
最终int螺纹数=8;
最终阻塞队列=新的LinkedBlockingQueue(200);
ExecutorService=Executors.newFixedThreadPool(线程计数);
对于(int i=0;i<(threadCount-1);i++){
提交(新的CalcTask(队列));
}
提交(新的ReadFileTask(队列,套接字)).get();
System.out.println(queue.size());//可以在这里看到计数
service.shutdownNow();
服务终止(365,时间单位:天);
对于(Map.Entry e:Map.entrySet()){
System.out.println(e.getKey());
}
socket.close();
serverSocket.close();
}
}
CalcTask:

Class CalcTask implements Runnable {
private final BlockingQueue<String> queue;

public CalcTask(BlockingQueue<String> queue) {
    this.queue = queue;
}

@Override
public void run() {
    String line;

    while (true) {
        try {
            //Queue is empty - so this block is not executing.
            line = queue.take();
            procesThis(line);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            break;
        }
    }
    while ((line = queue.poll()) != null) {
        procesThis(line);
    }
}
}
类CalcTask实现可运行{ 私有最终阻塞队列; 公共CalcTask(阻塞队列){ this.queue=队列; } @凌驾 公开募捐{ 弦线; while(true){ 试一试{ //队列为空-因此此块未执行。 line=queue.take(); procesThis(行); }捕获(中断异常例外){ 例如printStackTrace(); 打破 } } 而((line=queue.poll())!=null){ procesThis(行); } } } ReadFileTask:

class ReadFileTask implements Runnable {
private final BlockingQueue<String> queue;
private Socket socket;


public ReadFileTask(BlockingQueue<String> queue, Socket socket) {
    this.queue = queue;
    this.socket = socket;
}

@Override
public void run() {
    BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        for (String line; (line = br.readLine()) != null; ) {
            queue.put(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null) br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
}
class ReadFileTask实现可运行{
私有最终阻塞队列;
专用插座;
公共ReadFileTask(阻塞队列、套接字){
this.queue=队列;
this.socket=socket;
}
@凌驾
公开募捐{
BufferedReader br=null;
试一试{
br=新的BufferedReader(新的InputStreamReader(socket.getInputStream());
for(字符串行;(line=br.readLine())!=null;){
排队.放(线);
}
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}最后{
试一试{
如果(br!=null)br.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
请检查并让我知道这种方法可能有什么问题?

  • 不要继续重新创建服务器套接字。将其初始化移到循环之前。您的方式可能会导致绑定异常和客户端连接拒绝

  • 同样,您不应该在循环内创建ior或关闭executor服务


谢谢,我已按照您的建议将初始化移到顶部。目前,我还删除了循环(因此只有一个客户端连接并终止)。但我发现在执行“CalcTask”线程时共享BlockingQueue是空的。是否有关于如何调试此循环的指示?