有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程为什么我的java服务器程序在超时后不退出?

我一直在尝试使用通过我自己系统上的socket连接的客户机-服务器对来解决消费者-生产者问题。到目前为止一切都很顺利,但只剩下一个问题。我的服务器程序在超时后不会退出,而客户端会退出

我得到的客户端代码如下所示:

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.");
    }
}

以下是服务器代码:

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.");
    }
}

我说这些程序基本上已经在运行了,但我只是想在我提交之前问一下最后一个错误

我已经检查了done变量(我的exit标志)是否可以被服务器程序中的所有线程访问;因为它在客户机中。我还确保了done变量在main中接近末尾的适当点设置为true

关于如何解决这个错误有什么想法吗


共 (1) 个答案

  1. # 1 楼答案

    实际上,我成功地将操纵器的声明更改为由另一个线程直接调用的内容。那件事本身就解决了我的问题。很抱歉给那些已经试图解决我的问题的人带来不便。代码是为试图了解这个复杂问题的相关方准备的