나는 내 시스템의 소켓을 통해 연결된 클라이언트 - 서버 쌍을 사용하여 소비자 생산자 문제를 해결하려고 노력해 왔습니다. 지금까지 충분히 잘 진행되었지만 한 가지 문제 만 남아 있습니다. 내 서버 프로그램은 클라이언트가하는 동안 시간 초과 후에 종료되지 않습니다.시간 초과 후 왜 내 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로 설정되는 것보다 확실하게 만들었습니다.
이 오류를 해결하는 방법에 대한 의견이 있으십니까?