2014-11-30 2 views
0

나는 내 시스템의 소켓을 통해 연결된 클라이언트 - 서버 쌍을 사용하여 소비자 생산자 문제를 해결하려고 노력해 왔습니다. 지금까지 충분히 잘 진행되었지만 한 가지 문제 만 남아 있습니다. 내 서버 프로그램은 클라이언트가하는 동안 시간 초과 후에 종료되지 않습니다.시간 초과 후 왜 내 Java 서버 프로그램이 종료되지 않습니까?

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 변수 (내 종료 플래그)에 액세스 할 수 있는지 확인했다. 그것은 클라이언트 내에 있기 때문입니다. 나는 또한 done 변수가 메인에서 적절한 지점에서 끝으로 true로 설정되는 것보다 확실하게 만들었습니다.

이 오류를 해결하는 방법에 대한 의견이 있으십니까?

답변

0

실제로 Manipulator의 선언을 다른 스레드가 직접 호출 한 것으로 변경했습니다. 그 행동은 그 자체로 내 문제를 해결했습니다. 이미 문제를 해결하려는 사람들에게 불편을 끼쳐 드려 죄송합니다. 이 복잡한 문제를 배우려는 이해 당사자를위한 코드가 있습니다.

관련 문제