简体   繁体   English

为什么超时后我的Java服务器程序无法退出?

[英]Why won't my java server program exit after the time out?

I've been trying to solve the consumer-producer problem using a client-server pair connected via sockets on my own system. 我一直在尝试使用通过我自己系统上的套接字连接的客户端/服务器对解决消费者-生产者问题。 It's been going well enough so far, but only one problem remains. 到目前为止,它已经进行得足够好了,但是仍然只有一个问题。 My server program won't exit after the time out, while the client does. 超时后,我的服务器程序将不会退出,而客户端会退出。

The client code I've got is shown below: 我得到的客户端代码如下所示:

import java.util.*;
import java.net.*;
import java.io.*;

public class ConsumerClient {
    protected static boolean done = false;
    private static InetAddress host;
    private static final int PORT = 4545;

    private static BufferedReader inS;
    private static PrintWriter outS;
    private static Socket link;

    static class Consumer implements Runnable {
        Random random = new Random();

        @Override
        public void run() {
            try {
                while(true) {
                    String recieved;
                    try {
                        outS.println("1");
                    } catch(Exception e) {
                        System.out.println(e);
                    }
                    recieved = inS.readLine();
                    System.out.println("Recieved object: " + recieved);
                    if(done) {
                        System.out.println("Consumer done.");
                        outS.println("0");
                        return;
                    }
                }
            } catch(IOException e) {
                System.out.println(e);
            } catch (Exception e) {
                System.out.println(e);
            }
        }   
    }

    public static void main(String[] args) {
        //Allows the user to control the number of consumer threads
        Scanner keyboard = new Scanner(System.in);
        System.out.print("Enter number of consumers: ");
        int numConsumers = keyboard.nextInt();

        System.out.print("Enter how long (seconds) to run: ");
        int time = keyboard.nextInt();

        System.out.println("Client ready! Continue when server ready.");
        System.out.print("Type \"abort\" and press \"Enter\" to stop "
                + "immediately or type anything else to continue: ");
        String cmd = keyboard.next();

        if(!cmd.toLowerCase().equals("abort")) {
            try {
                System.out.println("Acquiring host...");
                host = InetAddress.getLocalHost();
                System.out.println("Connecting to server...");
                link = new Socket(host,PORT);
                System.out.println("Connection found.");
                inS = new BufferedReader(new InputStreamReader(
                        link.getInputStream()));
                outS = new PrintWriter(link.getOutputStream(),true);
            } catch(UnknownHostException e) {
                System.out.println(e);
                System.exit(1);
            } catch(IOException e) {
                System.out.println(e);
            }
            System.out.println("Connection established: " + host + ": "
                    + PORT);

            Consumer c = new Consumer();

            for (int i = 0; i < numConsumers; i++) {
                new Thread(c).start();
                System.out.println("Consumer " + (i+1) + " starts...");
            }

            try {
                Thread.sleep(time*1000);
            } catch(Exception e) {
                System.out.println(e);
            }
            System.out.println("Time out.");
        }

        done = true;
        System.out.println("Client shutting down.");
    }
}

And here's the server code: 这是服务器代码:

import java.util.*;
import java.io.*;
import java.util.concurrent.*;
import java.net.*;

public class ProducerServer {
    private static ServerSocket servSock;
    private static final int PORT = 4545;
    protected static boolean done = false;

    private static BufferedReader inS;
    private static PrintWriter outS;
    private static Socket link;

    static class Producer implements Runnable {
        protected BlockingQueue queue;
        Random random = new Random();

        Producer(BlockingQueue q) {
            queue = q;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Object justProduced = new Object();
                    queue.put(justProduced);
                    System.out.println("Object produced; List size is "
                            + queue.size());
                    if(done) {
                        System.out.println("Producer done.");
                        return;
                    }
                }
            }
            catch (InterruptedException e) {
                System.out.println(e);
            }           
        }
    }

    static class Manipulator implements Runnable {
        protected BlockingQueue queue;

        Manipulator(BlockingQueue q) {
            queue = q;
        }
        @Override
        public void run() {
            try {
                String request = inS.readLine();
                while(true) {
                    if(request.equals("0")) {Thread.sleep(100);}
                    if(request.equals("1")) {
                        Object obj = queue.take();
                        int len = queue.size();
                        System.out.println("Object taken; list size is " + len);
                        System.out.println("Sending object: " + obj);
                        outS.println(obj);
                    }
                    request = inS.readLine();
                    if(done){
                        System.out.println("Manipulator done.");
                        return;
                    }
                }
            } catch(Exception e) {
                System.out.println(e);
            }
        }       
    }


    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        System.out.print("Enter number of producers: ");
        int numProducers = keyboard.nextInt();

        System.out.print("Enter how long (seconds) to run: ");
        int time = keyboard.nextInt();

        System.out.println("Server ready! Continue when client ready.");
        System.out.print("Type \"abort\" and press \"Enter\" to stop "
                + "immediately or type anything else to continue: ");
        String cmd = keyboard.next();

        if(!cmd.toLowerCase().equals("abort")) {
            try {
                System.out.println("Opening port...");
                servSock = new ServerSocket(PORT);
                System.out.println("Awaiting client connection...");
                link = servSock.accept();
                System.out.println("New client found.\n");
                inS = new BufferedReader(new InputStreamReader(
                        link.getInputStream()));
                outS = new PrintWriter(link.getOutputStream(), true);
            } catch(IOException e) {
                System.out.println(e);
                System.exit(1);
            }
            System.out.println("Connection established on port: " + PORT);

            BlockingQueue myQueue = new ArrayBlockingQueue(10);

            for (int i = 0; i < numProducers; i++)
                new Thread(new Producer(myQueue)).start();

            Manipulator m = new Manipulator(myQueue);
            m.run();

            try {
                Thread.sleep(time*1000);
            } catch(Exception e) {
                System.out.println(e);
            }
            System.out.println("Time out.");
        }

        done = true;
        System.out.println("Server shutting down.");
    }
}

I say the programs are mostly working already, but I just wanted to ask about this last error before I turn it in. 我说这些程序已经可以正常工作了,但是我只是想问一下最后一个错误,然后再上交。

I've checked that the done variable (my exit flag) is accessible by all threads in the server program; 我检查了服务器程序中的所有线程都可以访问完变量(退出标志)。 as it is within the client. 因为它在客户端内。 I've also made sure than the done variable gets set to true in main at the appropriate point toward the end. 我还确保在结束时的适当时间点,将done变量设置为main。

Any thoughts on how I can solve this error? 关于如何解决此错误的任何想法?

Actually I managed to change the declaration of Manipulator into something directly called by another thread. 实际上,我设法将Manipulator的声明更改为另一个线程直接调用的内容。 That act solved my problem in itself. 该行为本身解决了我的问题。 Sorry for the inconvenience to those already trying to solve my problem. 造成您的不便,敬请见谅。 The code's there for interested parties trying to learn this complicated problem. 该代码供有兴趣的人士尝试学习此复杂问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM