0
我目前正在嘗試製作一個創建和寫入日誌文件的java程序。創建一個基於命令的記錄程序
它有2個類(一個用於請求,一個用於工作者代碼)。一個班級有一個文本字段並允許您輸入命令。命令應該像'log start'或'log stop'一樣。
所以請求類發送命令作爲一個字符串,工人階級獲取命令,對其進行解析並執行指令(開始記錄,停止記錄
我的問題是:當用戶進入應用程序不會停止記錄'停止'命令,並且它在3個日誌條目之後不會停止(這是問題,我想在用戶輸入命令時停止它),當你看看代碼時,你會更好地理解問題
我知道我在這裏犯了一個非常基本的錯誤,但不知何故目前無法弄清楚,並希望您對這個問題的看法(我在代碼中顯示有問題)謝謝
錯誤:
Exception in thread "stoplogging" java.lang.ArrayIndexOutOfBoundsException: 1
at Response$ClientProcess$1StopperThread.run(Response.java:109)
at java.lang.Thread.run(Unknown Source)
Request類:
public class Request extends JFrame {
private JTextArea consoleArea = new JTextArea();
private JTextField cmd_prompt = new JTextField();
private JLabel cmd_label = new JLabel("Enter command: ");
// ********IP PORT TEXTFIELDS & CONNECT BUTTON******* !!!!
private DataOutputStream output;
private DataInputStream input;
public static void main(String[] args) {
new Request();
}
Socket socket = null;
String command;
public Request(){
JPanel requestPanel = new JPanel();
requestPanel.setLayout(new BorderLayout());
setTitle("Project_3002_CLIENT");
requestPanel.add(cmd_label, BorderLayout.WEST);
requestPanel.add(cmd_prompt, BorderLayout.CENTER);
setLayout(new BorderLayout());
add(requestPanel, BorderLayout.NORTH);
add(new JScrollPane(consoleArea), BorderLayout.CENTER);
Font font = new Font("Courier New", Font.BOLD, 15);
cmd_prompt.setFont(font);
cmd_prompt.setAlignmentX(LEFT_ALIGNMENT);
cmd_prompt.addActionListener(new TextFieldListener());
setSize(600, 270);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
consoleArea.setFont(font);
setVisible(true);
String ip = "127.0.0.1"; // THIS WILL BE CHANGED (make custom) --extra jframe
int port = 4588; // THIS WILL BE CHANGED (make custom) -- extra jframe
try {
socket = new Socket(ip, port);
//IO connection stuff
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
}
catch (IOException ex) {
consoleArea.append("Connection refused. Please check if the server is running.\n");
}
}
class SenderThirty implements Runnable{
Thread send30secs;
public SenderThirty(){
}
public SenderThirty(String send30s){
send30secs = new Thread(this, send30s);
send30secs.start();
}
@Override
public void run() {
try {
output.writeUTF(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class TextFieldListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
try {
command = cmd_prompt.getText();
if (command.contains("start") == true){
Thread sendstart = new Thread(new SenderThirty(), "send");
sendstart.start();
//continue
}
else if (command.contains("stop") == true){
Thread sendstop = new Thread(new SenderThirty(), "send");
sendstop.start();
//continue
}
else {consoleArea.append("\nInvalid command\n");}
} catch (Exception e1) {
consoleArea.append("\nERR!\n");
}
}
}}
Worker類:
public class Response {
String path = "";
public static void main(String[] args) throws InterruptedException {
new Response();
}
ServerSocket resp_sock;
public Response() throws InterruptedException {
int port = 4588;
try {
resp_sock = new ServerSocket(port);
int clientNo = 1;
while (true) {
Socket socket = resp_sock.accept();
// client's IP address
InetAddress client_addr = socket.getInetAddress();
ClientProcess task = new ClientProcess(socket);
new Thread(task).start();
clientNo++;
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
class ClientProcess implements Runnable {
private Socket socket;
public ClientProcess(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
final DataInputStream input = new DataInputStream(socket.getInputStream());//from client
//DataOutputStream output = new DataOutputStream(socket.getOutputStream());//to client
while(true){
String prompt = input.readUTF();
String command[] = prompt.split(" ");
final Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
fh = new FileHandler("C:\\..path..\\logfile.log");
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
class StopperThread implements Runnable{
public StopperThread(){
}
@Override
public void run() {
try { ////////////////////////////////////////***PROBLEM IS IN THIS TRY BLOCK***
String next_prompt;
next_prompt = input.readUTF();
String nextCommand[] = next_prompt.split(" ");
if(nextCommand[1].equalsIgnoreCase("stop")){
logger.info("STOPPED " + new Date() + " \n");
System.exit(0);}
} catch (IOException e) {
e.printStackTrace();
}
}}
if(command[1].equalsIgnoreCase("start")){
try {
while(true){
logger.info("RUNNING " + new Date() + " \n");
Thread.sleep(5000);
Thread stoplogging = new Thread(new StopperThread(), "stoplogging");
stoplogging.start();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(command[1].equalsIgnoreCase("stop")){
logger.info("STOPPED " + new Date() + " \n");
}
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
}}
謝謝,我會解決這個問題。但我的主要問題仍然發生時,請求有2個項目[日誌,停止]第一項是微不足道的。我需要的是在停止請求進入的任何地方停止日誌記錄過程。它可以在1或2個日誌條目(它每5秒記錄一次)之後停止日誌記錄,但是在3個條目之後,如果我試圖停止,則不會發生任何事情,如果我命令幾次迅速,我得到ArrayIndexOutOfBoundsException。你有什麼意見嗎? – 2012-07-07 07:30:23
@AdamCosgrove有幾個潛在的問題,其中一個就是你在沒有正確同步的情況下跨線程共享數據。所以很可能一個線程發生了變化,其他線程看不到它。我建議你嘗試創建一個[SSCCE](http://sscce.org),它重現行爲併發佈一個新問題。 – assylias 2012-07-09 18:03:55