猿问

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

我需要创建一个新线程,当且仅当主 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 时就更新变量。


小怪兽爱吃肉
浏览 106回答 1
1回答

慕容708150

您可以使用条件变量来完成此操作。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();    }}@Overridepublic 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();}@Overridepublic void onMessageReceived(MessageReceivedEvent event) {    queue.put(event);}您可以使用Callback,这是我推荐的。Consumer<? super MessageReceivedEvent> callback;private void onInput(Consumer<? super MessageReceivedEvent> callback) {    this.callback = callback;}@Overridepublic 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());});
随时随地看视频慕课网APP

相关分类

Java
我要回答