java - 基于控制台的应用程序不显示建议

标签 java console-application java.util.scanner

我正在开发一个基于控制台的 Java 应用程序。我必须向用户展示选择数据库的建议。我正在使用 Scanner 读取输入,并使用一个单独的线程检查输入是否包含 TAB 以便打印建议。

更新

按照下面的回答,我在代码中添加了同步块(synchronized block),异常消失了。但是,我没有在控制台上看到任何建议。以下是我当前的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Test {

    private static List<String> suggestions = new ArrayList<>();

    private static final Object lock = new Object();

    public static void main(String[] arguments) {

        suggestions.add("H2");
        suggestions.add("Mongo");
        suggestions.add("MySQL");
        suggestions.add("Oracle");
        suggestions.add("PostgreSQL");
        suggestions.add("SQLite");

        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter a database name, press TAB for suggestions");

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    synchronized (lock) {
                        if (scanner.hasNext()) {
                            String input = scanner.next();
                            if (input.contains("\\t")) {
                                System.out.println(getSuggestions(input));
                            }
                        }
                    }
                }
            }
        }).start();

        synchronized (lock) {
            String selectedDatabase = scanner.nextLine();
            System.out.println(selectedDatabase);
        }

    }

    private static List<String> getSuggestions(String input) {
        List<String> possibleSuggestions = new ArrayList<>();
        for (String suggestion : suggestions) {
            if (suggestion.startsWith(input)) {
                possibleSuggestions.add(suggestion);
            }
        }
        return possibleSuggestions;
    }

}

有人可以帮忙吗?

最佳答案

简单地说,Scanner 不是线程安全的类,您在两个不同的线程中使用它。

您在主线程中实例化扫描仪并在另一个线程中使用它。在后台,Scanner 的构造函数可能已初始化字段,这些字段不一定同步到其他线程。

当另一个线程运行时,您在主线程中执行 scanner.nextLine(),这可能与另一个执行 scanner.hasNext() 的线程同时执行,导致并发访问。

您需要一种方法来同步对扫描仪的访问(无处不在),例如通过

synchronized (lock) {
    if (scanner.hasNext()) {
        String input = scanner.next();
        if (input.contains("\\t")) {
            System.out.println("ok");
        }
    }
}

其中锁定是您同步的静态字段:

private static final Object lock = new Object();

关于java - 基于控制台的应用程序不显示建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45036600/

相关文章:

java - Neo4j 中具有一级关系的路径

在循环外声明的 C# 变量在循环中被赋值但得到 'Unassigned' 编译错误

java - 使用多台扫描仪有什么好处?

c# - 控制台应用程序相互通信的推荐方式是什么?

c++ - 在初始化二维数组然后将其发送给函数时遇到一些问题

Java 将字符串与正则表达式进行比较 - while 循环

java - 为什么扫描仪会跳过用户的输入

java - DDD valueObject 和数据库模式

java - 将整数排列的完整 ArrayLists 排序为决策树结构

java - 什么是 Eclipse "Dynamic Web Module"编号,为什么 JAX-RS 不在项目方面列表中?