0

私のプロジェクトでこの問題が2日間発生しています..そして、何が問題なのかわかりません。私のプロジェクトには、メインと、ExecutorService を使用して ProcessBuilder 経由で呼び出される別のクラスの 2 つのクラスが含まれています。ここにコードがあります。

メインクラス:

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();
        }
    }
}

そう。ボタンを 1 回クリックすると、出力は次のようになります。

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

しかし、アプリケーションを閉じてから再度起動し、最初のクリックで何も入力せずにボタンを 2 回クリックすると、出力は次のようになります。

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 つの入力を登録していると思います。ただし、最初のクリックで入力し、2 回目のクリックで入力が得られず、もう一度ボタンをクリックすると、ストリームは 2 つの入力を登録せず、1 つだけ登録します。

まず、ボタンをクリックするとプロセスが破棄され、bufferedwriter が再度インスタンス化されるため、これは発生しないはずです。または、私が間違っている可能性があります。

あなたが私の主張を理解してくれることを願っています。ありがとうございました。

4

0 に答える 0