Java 睡眠(时间)不是我所需要的方式。我需要更好的

Java 睡眠(时间)不是我所需要的方式。我需要更好的,java,Java,我是丹麦的一名学生,想做一个学校项目。我现在正在研究的是一个reader类,它接收一个字符串,然后逐字和/或逐字打印出来 我做了一些研究,发现Thread.sleep(time)正是我所需要的。但在我使用它之后,我发现它不能正常工作!我尝试了更多的研究,发现了一个叫做ThreadPoolExecutor的东西,但我能弄清楚它在我的案例中是如何工作的 我的读者: public class TextReader { // Print method to print word by word

我是丹麦的一名学生,想做一个学校项目。我现在正在研究的是一个reader类,它接收一个字符串,然后逐字和/或逐字打印出来

我做了一些研究,发现
Thread.sleep(time)
正是我所需要的。但在我使用它之后,我发现它不能正常工作!我尝试了更多的研究,发现了一个叫做
ThreadPoolExecutor
的东西,但我能弄清楚它在我的案例中是如何工作的

我的读者:

public class TextReader {

    // Print method to print word by word from a string
    public void wordByWord(String text) throws InterruptedException {
        String[] words = text.split(" ");
        for (int i = 0; i < words.length; i++) {
            System.out.print(words[i] + " ");
            Thread.sleep(250);
        }
    }

    // Print method to print letter by letter from a string
    public void letterByLetter(String text) throws InterruptedException {
        String[] words = text.split(" ");
        for (int i = 0; i < words.length; i++) {
            String word = words[i] + " ";
            char[] letters = (word.toCharArray());
            for (int j = 0; j < letters.length; j++) {
                System.out.print(letters[j]);
                Thread.sleep(250); //so it does not print all the letters at once
            }
        }
    }
}
公共类文本阅读器{
//Print方法从字符串中逐字打印
public void wordByWord(字符串文本)引发InterruptedException{
String[]words=text.split(“”);
for(int i=0;i

Thread.sleep(time)
在我的例子中不起作用的原因是因为我需要打印到控制台,并且通过使用
Thread.sleep(time)
它不会像瀑布一样打印。它要么打印我试图分解的字符串(时间小于250ms),要么一次打印几个字母(250ms),要么太慢了,我看不见它。。。(超过250毫秒)。我需要它跑得又快又平稳!所以它看起来像是有人在写它。

你所做的就是在这段时间里让一条线索进入睡眠状态。这意味着该线程将在该时间之后解除阻塞,但是您没有考虑从另一个线程切换上下文的开销

线程的sleep方法在指定的毫秒内停止当前线程的执行需要毫秒。如果它慢,你可以通过更少的毫秒,如果它快,那么你可以增加计时。因此,您可以根据需要进行调整

执行框架是另一回事。
这是一种将可运行任务提交给ExecutorFramework管理的线程的方法。

我想我成功地重新创建了您的问题。每一次低于约205 ms的延迟似乎都会导致更新问题。有时,单词/字母不会出现,但在下一个时间间隔,多个单词/字母同时出现

这似乎是控制台I/O性能的一个限制()。对此你真的无能为力。如果您想以这样短的、最小的延迟输出文本,您需要编写自己的GUI(例如)。这可能会解决性能问题

不同延迟下的输出 205毫秒

190毫秒

尝试了
ScheduledExecutorService
方法,似乎效果不错。有一些优化需要完成,也有一些困难需要跳过,以等待预定的打印完成,但它似乎没有显示延迟(在我尝试的两个控制台中——Eclipse输出和Windows Bash)

公共类输出{
公共静态void main(字符串[]args){
String toPrint=“你好,我叫伏地魔,但很少有人这么叫我。”;
StringPrinter打印机=新的StringPrinter();
打印机。打印(TopPrint,输出::按字符,30);
System.out.println();
打印机。打印(TopPrint,输出::byWord,150);
}
私有静态列表字节(字符串到拆分){
Iterable it=()->新扫描仪(toSplit);
返回StreamSupport.stream(it.spliterator(),false).map(s->s+).collect(Collectors.toList());
}
私有静态列表按字符(字符串到拆分){
返回toSplit.chars().mapToObj(i->“”+(char)i.collect(Collectors.toList());
}
}
类StringPrinter实现可运行{
//使用阵列是最有效的
私有字符串[]输出;
私有int-currentIndex;
//提供毫秒延迟的服务
私有ScheduledExecutorService打印执行器;
公共无效打印(字符串输出、函数拆分、整数延迟){
如果(printExecutor!=null){
抛出新的非法状态异常();
}
printExecutor=Executors.newSingleThreadScheduledExecutor();
列表=拆分。应用(toOutput);
output=list.toArray(新字符串[list.size()]);
currentIndex=0;
printExecutor.scheduleWithFixedDelay(这个,0,延迟,时间单位为毫秒);
//等待输出完成
已同步(此){
while(printExecutor!=null)
试一试{
wait();//等待打印完成
}捕获(中断异常e){}
}
}
@凌驾
公开募捐{
if(当前索引<输出长度){
System.out.print(输出[currentIndex++]);
}否则{
//将此打印运行标记为已完成
printExecutor.shutdown();
printExecutor=null;
已同步(此){notifyAll();}
}
}
}

“Thread.sleep(time)太慢”mfwIf如果您只想让它快速运行,请删除增加延迟的代码。现在还不清楚你为什么要暂停你的节目。“使用Thread.sleep(时间)它有点滞后”是的,这就是代码的全部要点,暂停程序250ms。打印后尝试刷新<代码>System.out.flush()250毫秒延迟的目的是什么?使用ScheduledExecutorService并以固定速率提交单个打印。我认为您的思路是正确的。但在我的代码中会是什么样子呢?仍然
public class Output {
    public static void main(String[] args) {
        String toPrint = "Hello, my name is Voldemort, but few call me that.";
        StringPrinter printer = new StringPrinter();
        printer.print(toPrint, Output::byCharacter, 30);
        System.out.println();
        printer.print(toPrint, Output::byWord, 150);
    }

    private static List<String> byWord(String toSplit) {
        Iterable<String> it = () -> new Scanner(toSplit);
        return StreamSupport.stream(it.spliterator(), false).map(s -> s + " ").collect(Collectors.toList());
    }

    private static List<String> byCharacter(String toSplit) {
        return toSplit.chars().mapToObj(i -> "" + (char) i).collect(Collectors.toList());
    }
}

class StringPrinter implements Runnable {
    // using an array to be most efficient
    private String[] output;
    private int currentIndex;

    // the service providing the milliseconds delay
    private ScheduledExecutorService printExecutor;

    public void print(String toOutput, Function<String, List<String>> split, int delay) {
        if (printExecutor != null) {
            throw new IllegalStateException();
        }
        printExecutor = Executors.newSingleThreadScheduledExecutor();
        List<String> list = split.apply(toOutput);
        output = list.toArray(new String[list.size()]);
        currentIndex = 0;

        printExecutor.scheduleWithFixedDelay(this, 0, delay, TimeUnit.MILLISECONDS);

        // wait until output has finished
        synchronized (this) {
            while (printExecutor != null)
                try {
                    wait(); // wait for printing to be finished
                } catch (InterruptedException e) {}
        }
    }

    @Override
    public void run() {
        if (currentIndex < output.length) {
            System.out.print(output[currentIndex++]);
        } else {
            // mark this print run as finished
            printExecutor.shutdown();
            printExecutor = null;
            synchronized (this) { notifyAll(); }
        }
    }
}