Java: how to abort a thread reading from System.in

前端 未结 6 2071
梦谈多话
梦谈多话 2020-12-01 14:35

I have a Java thread:

class MyThread extends Thread {
  @Override
  public void run() {
    BufferedReader stdin =
        new BufferedReader(new InputStream         


        
6条回答
  •  孤城傲影
    2020-12-01 15:28

    JavaDoc for BufferedReader.readLine:

    Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

    Based on this, I don't think it'll ever return null (can System.in actually be closed, I don't think it ever returns end of stream?), so the while-loop won't terminate. The usual way to stop a thread is either use a boolean variable in a loop condition and change it from outside of the thread or call the Thread-objects' interrupt() -method (only works if the thread is wait():ing or sleep():ing, or in a blocking method that throws InterruptedException). You can also check if the thread has been interrupted with isInterrupted().

    Edit: Here's a simple implementation utilizing isInterrupted() and interrupt(). The main-thread waits 5 seconds before interrupting the worker-thread. In this case worker-thread is basically busy-waiting, so it's not that good (looping all the time and checking stdin.ready(), you could of course let the worker-thread sleep for a while if no input is ready):

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    
    public class MyThreadTest
    {
        public static void main(String[] args)
        {
            MyThread myThread = new MyThread();
            myThread.start();
    
            try
            {
                Thread.sleep(5000);
            }
            catch(InterruptedException e)
            {
                //Do nothing
            }
    
            myThread.interrupt();
    
        }
    
        private static class MyThread extends Thread
        {       
            @Override
            public void run()
            {
                BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
                String msg;
    
                while(!isInterrupted())
                {
                    try
                    {
                        if(stdin.ready())
                        {
                            msg = stdin.readLine();
                            System.out.println("Got: " + msg);
                        }
                    }
                    catch(IOException e)
                    {
                        e.printStackTrace();
                    }
                }           
                System.out.println("Aborted.");
            }
        }
    
    }
    

    It seems there's no way to actually interrupt the BufferedReader if it's blocked on readline, or at least I couldn't find one (using System.in).

提交回复
热议问题