为了账号安全,请及时绑定邮箱和手机立即绑定

仅当主监听器更新时,如何将主事件监听器中的 MesageReceivedEvent

仅当主监听器更新时,如何将主事件监听器中的 MesageReceivedEvent

小怪兽爱吃肉 2023-08-16 10:07:14
我需要创建一个新线程,当且仅当主 ListenerAdapter 内更新 MessageReceivedEvent 时才会执行一个方法,并在变量未更新时让线程休眠。该线程应独立于主线程运行,并且不会停止新请求。这是线程类,private static final class Worker extends Thread {        private volatile boolean running = false;MessageReceivedEvent event; //this must update along with the listener        private boolean validateData() {            if (//something) {                return true;            }            return false;        }        private void waitForInput() {            boolean hasInput = false;            try {                while (!hasInput) {                    hasInput = validateData();                    if (!hasInput) {                        Thread.sleep(10);                    }                }            } catch (InterruptedException iex) {                Thread.currentThread().interrupt();            }        }        @Override        public void run() {            running = true;            while (running) {                waitForInput();                //do something            }        }    }它是一个由主线程请求运行的内部类,只有当来自侦听器的实际事件发生变化时,才必须更新其中的 MessageReceivedEvent,否则它不应该执行任何操作。测试时,只会根据触发该线程的MessageEvent执行,如何让该线程接收到更新?public class Listener extends ListenerAdapter {    public static MessageReceivedEvent msgEvnt;    @Override    public void onMessageReceived(MessageReceivedEvent msgEvnt) {                    Listener.msgEvnt = msgEvnt;    }这就是侦听器所做的全部工作,每当有新的 messageEvent 时就更新变量。
查看完整描述

1 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

您可以使用条件变量来完成此操作。

final ReentrantLock lock = new ReentrantLock();

final Condition condition = lock.newCondition();


private void waitForInput() {

    lock.lock();

    Listener.msgEvnt = null;

    try {

        while (Listener.msgEvnt == null)

            condition.await();

    } catch (InterruptedException e) {

        e.printStackTrace();

    } finally {

        lock.unlock();

    }

}


@Override

public void onMessageReceived(MessageReceivedEvent event) {

    lock.lock();

    try {

        Listener.msgEvnt = msgEvnt;

        condition.signal();

    } finally {

        lock.unlock();

    }

}

请参阅可重入锁和条件


您可以使用阻塞队列

final BlockingQueue queue = new ConcurrentBlockingQueue();


private MessageReceivedEvent waitForInput() throws InterruptedException {

    return queue.take();

}


@Override

public void onMessageReceived(MessageReceivedEvent event) {

    queue.put(event);

}

您可以使用Callback,这是我推荐的。

Consumer<? super MessageReceivedEvent> callback;


private void onInput(Consumer<? super MessageReceivedEvent> callback) {

    this.callback = callback;

}


@Override

public void onMessageReceived(MessageReceivedEvent event) {

    if (this.callback != null)

        this.callback.accept(event);

    this.callback = null;

}

使用示例:


listener.waitForInput(event -> {

    System.out.printf("%#s: %s\n", event.getAuthor(), event.getMessage().getContentDisplay());

});


查看完整回答
反对 回复 2023-08-16
  • 1 回答
  • 0 关注
  • 101 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信