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