0

我的项目有这个问题两天了。我不确定是什么问题。我的项目包括 2 个类,主类和另一个使用 ExecutorService 通过 ProcessBuilder 调用的类。这是代码。

主类:

public class DesktopApplication1View extends FrameView{
        public Process process = null;
        private executeCode execute = new executeCode();

public DesktopApplication1View(SingleFrameApplication app){

        (.........)

        jButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                console.setText("");
                execute.start();
            }
        });

    }


    class executeCode implements Runnable{
            private boolean executeStarted = false;
            private ExecutorService executecode;

            ReadStdout read;
            WriteStdin write;

            public executeCode(){
                executecode = Executors.newSingleThreadExecutor();
                read = new ReadStdout();
                write = new WriteStdin();
            }

            public void start(){

                     if(executeStarted){
                        try {
    //                        process.getInputStream().close();
                            process.getOutputStream().close();
                            process.destroy();
                        } catch (IOException ex) {}
                     }

                     console.append("start\n");//debugging purpose
                     executecode.execute(this);
            }

            public void run(){
                console.append("Execute thread = " + Thread.currentThread().getName() + "\n");//debugging purpose
                     executeStarted = true;
                try {
                                    ProcessBuilder builder = new ProcessBuilder("java", "-cp", "Project.jar", "project/oddeven");
                                    builder.redirectErrorStream(true);
                                    process = builder.start();
                                    read.startReadStdout();
                                    write.startWriteStdin();
                                }
                        catch (IOException e1) {console.append("error io");}
    //                return;
                    }
        }


        class WriteStdin implements Runnable{
        private String input = null;
        private BufferedWriter writer = null;
        private ExecutorService executeWrite = Executors.newSingleThreadExecutor();

        public void startWriteStdin(){
            writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

            executeWrite.execute(this);
        }
        public void WriteStdin(){

            console.addKeyListener(new java.awt.event.KeyAdapter() {

                @Override
                public void keyTyped(java.awt.event.KeyEvent e){

                    //save the last lines for console to variable input
                    if(e.getKeyChar() == '\n'){

                        try {
                            int line = console.getLineCount() -2;
                            int start = console.getLineStartOffset(line);
                            int end = console.getLineEndOffset(line);
                            input = console.getText(start, end  - start);
                            writer.write(input);
                            writer.flush();
                        } catch (Exception e1) {}
                    }
                }
            });
        }


        @Override
        public void run(){
             console.append("Write thread = " + Thread.currentThread().getName() + "\n");//debugging purpose
            if(input == null) this.WriteStdin();

        }
    }


    class ReadStdout implements Runnable{
        private ExecutorService executeRead = Executors.newSingleThreadExecutor();
        private BufferedReader reader = null;

        public void startReadStdout(){
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            executeRead.execute(this);
        }

        public void run() {
            console.append("Read thread = " + String.valueOf(Thread.currentThread().getName()) + "\n");//debugging purpose
            String line;
            try {
            while((line = reader.readLine())!=null)
              console.append(line+"\n");
                 }catch (IOException e) {}

            console.append("read done");//debugging purpose

        }
    }

奇偶类:

public class oddeven{
            static double num = 0;
            static int even = 0, odd = 0, zero = 0;
    public static void main(String[]args) throws Exception{
        odd();
    }
    public static void odd() throws Exception{
        try{
            BufferedReader dataIn = new BufferedReader(new InputStreamReader(System.in));
            System.out.print("Enter numbers\n(Input negative value to end)\n");
            num = Double.parseDouble(dataIn.readLine());
            while(num>=0){
                if(num == 0)
                    zero++;
                else if(num%2==0)
                    even++;
                else
                    odd++;
                num = Double.parseDouble(dataIn.readLine());
            }
            System.out.print("There are\n"+even+" even numbers\n"+odd+" odd numbers\n"+zero+" zero value");

        } catch(NumberFormatException e){
            System.out.print("Wrong input, enter again\n");
            odd();
        }
    }
}

所以。如果我单击一次按钮,则输出为:

start
Execute thread = pool-2-thread-1
Read thread = pool-3-thread-1
Write thread = pool-4-thread-1
Enter numbers
(Input negative value to end)
1
2
-1
There are
1 even numbers
1 odd numbers
0 zero value
read done

但是如果我关闭然后再次启动应用程序然后单击按钮两次而不在第一次单击时输入任何内容,输出将是:

start
Execute thread = pool-2-thread-1
read doneRead thread = pool-3-thread-1
Write thread = pool-4-thread-1
Enter numbers
(Input negative value to end)
1
2
-1
There are
2 even numbers
2 odd numbers
0 zero value
read done

如您所见,当我单击按钮两次而不在第一次单击时输入时,输出流没有关闭,我认为这导致奇偶类从流中注册了 2 个输入。但是,如果您在第一次单击时输入然后第二次单击没有得到任何输入并且您再次单击该按钮,则流将不再注册 2 个输入,它只会注册一个。

这不应该发生,因为首先,如果您单击按钮并且再次实例化缓冲写入器,则该进程将被破坏。或者我可能是错的。

我希望你明白我的意思。谢谢你。

4

0 回答 0