java - 遍历具有不同长度延迟的文本

标签 java loops runnable bukkit

  • Bukkit/Spigot API - https://hub.spigotmc.org/javadocs/spigot/
    好的,我正在尝试为我的服务器制作一个教程系统。我经常看到人们显示这样的文字:

    public void send(String...strings) {
        for (String string : strings) {
            player.sendMessage(string);
        }
    }
    

    .. 这太糟糕了。如您所知,它会向聊天发送垃圾邮件并使其不可读。
    因此,我使用 runnables 以一定的延迟显示文本。我可以轻松地制作具有相同特定延迟(即 30 个滴答)的可运行对象,但我希望可运行对象具有基于字符串的 length() 的延迟。

    我试着这样做:

    public void send(String...strings) {
        for (String string : strings) {
            new BukkitRunnable() {
                @Override
                public void run() {
                    player.sendMessage(string);
                }
            }.runTaskLater(my_plugin_instance, (string.length()*2));
        }
    }
    

    有了这个,是的,它占用了字符串的长度,但是 for 循环 在 runnable 显示文本之前继续到下一个字符串。
    所以如果我有这些句子(以正确的顺序):

    • 欢迎来到服务器,玩家!
    • 这个服务器是关于 blablabla、这个和那个以及更多的那个和这个
    • 接受教程?


    顺序将是

    • 接受教程?
    • 欢迎来到服务器,玩家!
    • 这个服务器是关于 blablabla、这个和那个以及更多的那个和这个

    我该怎么办?

最佳答案

您可能需要考虑使用一个单独的对象(即单例)充当打印机来打印所有消息。这将避免创建过多线程。

下面的解决方案使用 BlockingQueue 来让打印线程等待下一条消息。当消息不在队列中时 - run() 方法将等待而不会消耗太多 CPU。

解决方案有两种: - 如果您首先取消注释 msgQueue - 您将获得 sendMessage 的阻塞行为;该方法将等到所有项目都打印出来。 - 如果您取消推荐第二个 msgQueue - 消息将被添加到队列中而无需等待打印。

我添加了 ExecutorService 来管理线程,因为 Oracle/Java 认为这是使用 ExecutorServices 管理线程的良好实践。一旦不需要 MessagePrinter - 它由“executor.shutdownNow();”发出信号并平静地结束。

希望这对您有所帮助。

package stackoverflow;

import java.util.Arrays;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

class MessagePrinter implements Runnable {

    private static MessagePrinter instance;
    private MessagePrinter() {};

    // Uncomment the one below to make sendText wait until methods until all items are printed:
    // BlockingQueue<String> msgQueue = new LinkedBlockingQueue<>(1);

    // Uncomment the one below to make sendText not wait until messages are printed:
    BlockingQueue<String> msgQueue = new LinkedBlockingQueue<>(1);

    public void run() {
        try {
            while (true) { 
                String str = msgQueue.take();
                Thread.sleep( str.length() );
                TimeUnit.MILLISECONDS.sleep( str.length() * 10 );

                System.out.println(str);
            }
        } catch (InterruptedException e) {
            System.out.println("Quitting...");
            return;
        }
    }

    public void sendText(String... txt) {
        Arrays.asList(txt).stream().forEach(t -> {
            try {
                msgQueue.put(t);
            } catch (InterruptedException e) {
                // Received request to terminate.
                return;
            }
        });
    }

    synchronized public static MessagePrinter getInstance() {
        if (instance == null)
            instance = new MessagePrinter();
        return instance;
    }
}

public class VarDelay {

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        MessagePrinter msp = MessagePrinter.getInstance(); 

        executor.submit(msp);

        msp.sendText(new String[] {"Welcome to the server, player!",
                "This server is about blablabla, this and that and a bit more of that and this",
                "Accept the tutorial?" });

        msp.sendText("More text to follow");

        // Shutdown:
        executor.shutdown();
        if (!executor.awaitTermination(2, TimeUnit.SECONDS)) {
            executor.shutdownNow();
        }
    }
}

关于java - 遍历具有不同长度延迟的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40169109/

相关文章:

java - 外部循环运行我的程序 1000 次并保持计数 - Java

java - 调用start方法时,是否需要在java的run方法中同步方法?

java - 在不使用 Runnable 和 Timer 类的情况下定期调用方法

python - 如何在 Tkinter 中循环显示 jpg 的子文件夹?

android - 7 个线程/runnable 是不是太多了?是什么让我的应用程序变慢了?

java - Process.exitValue() 和 Process.destroy() 功能

java - Grails 应用程序 - Tomcat 与 Weblogic 上的 JNDI

Java正则表达式边界匹配?

java - 我如何使用 JAXB 解码

javascript - 我的 if 语句返回意外结果,用 Javascript 制作随机数独