使线程从其他线程跳过读取输入操作

时间:2016-07-04 07:01:58

标签: java multithreading

我创建了两个一起用于套接字连接的线程:SocketIn和SocketOut(它们都在while(true)语句中工作。在某些时刻我需要SocketOut线程停止等待键盘输入继续执行以下操作指令,即使他已经读取了一个空值,我需要这样做而不关闭线程或取出时间(真)。我不知道如何做到这一点,所以我需要一些建议。

2 个答案:

答案 0 :(得分:1)

了解CSP编程和BlockingQueue。您可以在循环中使用接受"命令"的队列。其中一个命令是从套接字输入的,另一个命令是从键盘输入的。

private final BlockingQueue<Command> inputChannel = new SynchronousQueue<>();

public void run() {
    while (true) {
        Command request = this.inputChannel.take();

        if (request instanceof Command.KeyboardInput) {
            ...

        } else {
            ...
        }
    }
}

答案 1 :(得分:0)

您可以再引入一个线程来阅读键盘。然后添加一些具有丰富中断功能的“通道”,从键盘读取器到套接字写入器(例如一些BlockingQueue):

class SocketApp {
    public static void main(String[] args) throws IOException {
        ExecutorService pool = Executors.newCachedThreadPool();

        URL url = new URL("http://...");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setDoOutput(true);

        OutputStream dst = con.getOutputStream();
        InputStream src = con.getInputStream();

        // channel between keyboard reader and socket writer
        BlockingQueue<Integer> consoleToSocket = new ArrayBlockingQueue<>(256);

        // keyboard reader
        pool.submit(() -> {
            while (true) {
                consoleToSocket.put(System.in.read());
            }
        });

        // socket writer
        pool.submit(() -> {
            while (true) {
                dst.write(consoleToSocket.take());
            }
        });

        // socket reader
        pool.submit(() -> {
            while (true) {
                System.out.println(src.read());
            }
        });
    }
}

// Now you can use different features of BlockingQueue.
// 1. 'poll' with timeout
// socket sender
pool.submit(() -> {
    while (true) {
        Integer take = consoleToSocket.poll(3, TimeUnit.SECONDS);
        if (take != null) {
            dst.write(take);
        } else {
            // no data from keyboard in 3 seconds
        }
    }
});

// 2. Thread interruption
// socket sender
pool.submit(() -> {
    while (true) {
        try {
            Integer take = consoleToSocket.take();
            dst.write(take);
        } catch (InterruptedException e) {
            // somebody interrupt me wait for keyboard
        }
    }
});