簡體   English   中英

Java互動式控制台

[英]Java interactive console

我目前正在開發Java命令行應用程序,並且希望使其具有交互性。 我的意思是,我有2個線程:

  • 一個線程正在向stdout永久寫入一些信息
  • 第二個線程僅從stdin讀取並正在等待用戶的一些命令

但是要點是,當我在第一個線程向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是一個PrintStreamSystem.in是一個InputStream並且它們是不同的對象(和流),但是它們都使用相同的源( 我猜您的情況是IDE控制台或命令提示符 ),因此當2個或更多線程將嘗試使用如果使用相同的源,則您將得到您提到的行為,因為默認情況下,主機環境或用戶使用相同的源/控制台。 Java來源閱讀以下內容:

系統輸出

/ ** *“標准”輸入流。 *該流已經打開並准備提供輸入數據。 通常,此流*對應於鍵盤輸入或主機環境或用戶指定的另一個輸入源 * /

系統輸入

/ ** *“標准”輸出流。 *該流已經打開並准備接受輸出數據。 通常,此流*對應於主機環境或用戶指定的顯示輸出或另一個輸出目標*


據我所知,實際上沒有此類API可以幫助您找到所需的內容,但是圍繞這些選項有一些解決方法:

請注意,恕我直言,選項3或任何基於同步的類似解決方案都是您不想要的,因為它會限制輸出的功能

選項1:

配置其他控制台設備,然后使用System.console()進行訪問。 在這種情況下,您將有不同的來源來讀取和寫入控制台,因此您將無法獲得所看到的內容。 如果您未明確配置任何內容,則默認情況下,您將獲得System.console()NULL

選項2:

與其將輸出寫入控制台,不如使用文件來寫入輸出。 這將確保您的輸入和輸出流不會互相混淆。

選項3:

如果您對控制台的讀取和寫入具有相同的來源,請同步訪問。 以下是相同的代碼,但是請注意,在獲取和釋放對象鎖時,您仍然會看到一些重疊,但是一旦在System.outSystem.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM