[英]Java interactive console
我目前正在開發Java命令行應用程序,並且希望使其具有交互性。 我的意思是,我有2個線程:
但是要點是,當我在第一個線程向stdout寫東西時輸入命令時,這確實很煩人,命令是“ cut”。
例如:我想鍵入命令“ set infolevel 2”,而在我鍵入該命令時,第一個線程輸出“一些信息1234”。
我的控制台輸出可能如下所示:
set inf // user typing command into stdin
some information 1234 // first thread writes out information
olevel 2 // continuing reading command from stdin
如果有人可以告訴我是否有類似的庫/ API,那將是非常糟糕的。 謝謝!
我猜您將使用System.out.println
輸出到控制台和new Scanner(System.in);
用於讀取輸入。
本質上, System.out
是一個PrintStream
而System.in
是一個InputStream
並且它們是不同的對象(和流),但是它們都使用相同的源( 我猜您的情況是IDE控制台或命令提示符 ),因此當2個或更多線程將嘗試使用如果使用相同的源,則您將得到您提到的行為,因為默認情況下,主機環境或用戶使用相同的源/控制台。 從Java來源閱讀以下內容:
系統輸出
/ ** *“標准”輸入流。 *該流已經打開並准備提供輸入數據。 通常,此流*對應於鍵盤輸入或主機環境或用戶指定的另一個輸入源 。 * /
系統輸入
/ ** *“標准”輸出流。 *該流已經打開並准備接受輸出數據。 通常,此流*對應於主機環境或用戶指定的顯示輸出或另一個輸出目標* 。
據我所知,實際上沒有此類API可以幫助您找到所需的內容,但是圍繞這些選項有一些解決方法:
請注意,恕我直言,選項3或任何基於同步的類似解決方案都是您不想要的,因為它會限制輸出的功能
配置其他控制台設備,然后使用System.console()
進行訪問。 在這種情況下,您將有不同的來源來讀取和寫入控制台,因此您將無法獲得所看到的內容。 如果您未明確配置任何內容,則默認情況下,您將獲得System.console()
為NULL
與其將輸出寫入控制台,不如使用文件來寫入輸出。 這將確保您的輸入和輸出流不會互相混淆。
如果您對控制台的讀取和寫入具有相同的來源,請同步訪問。 以下是相同的代碼,但是請注意,在獲取和釋放對象鎖時,您仍然會看到一些重疊,但是一旦在System.out
或System.in
上獲取或釋放了鎖,則不會看到重疊。
public class Test {
static Object object = new Object();
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object) {
Date date = new Date();
System.out.println("I am coming from first thread i.e. " + Thread.currentThread().getId() + " : " + date);
}
}
}
}.start();
new Thread(){
@Override
public void run() {
Scanner scanner = new Scanner(System.in);
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object) {
scanner.next();
}
}
}
}.start();
}
}
似乎您需要在某種對象上同步兩個線程。 像這樣: private Object lockObject = new Object(); Thread t1 = new Thread() { public void run() {synchronized( lockObject ){ //your code } } };
private Object lockObject = new Object(); Thread t1 = new Thread() { public void run() {synchronized( lockObject ){ //your code } } };
您可以按照他的答案中的建議使用鎖定,也可以修改代碼,以使一個線程同時進行輸入和輸出,而另一個線程進行計算。 使用ArrayBlockingQueue
將工作線程的輸出發送到I / O線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.