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

如何向 Android 线程发出信号以执行方法?

如何向 Android 线程发出信号以执行方法?

慕码人8056858 2022-06-30 11:51:32
我想产生一个休眠的线程,然后在接收到信号时执行一个方法。一旦方法完成,线程应该回到睡眠状态,等待下一个信号。传入的信号足够频繁,以至于我不希望每次信号传入时都产生新线程的开销。目前,我正在轮询信号,但我相信有更好的方法来做到这一点。我见过使用 Handler 和 AsyncTask 的例子,但我不太确定最好的实现是什么。有什么建议么?public ModuleFeedbackTask extends Thread{    RadioModule radioModule;    public ModuleFeedbackTask(RadioModule radioModule)    {        this.radioModule = radioModule;    }    @Override    public void run()    {        //Previously just called the function        //moduleUpdateTask();        //Currently polling for an update        //What I want to do is sleep until I get some signal        while(mState == JOB_STATE_RUNNING)        {            //Poll module             moduleUpdateTask();            //Sleep            sleep(5);        }    }    public moduleUpdateTask()    {        //Check if module is ready for processing        if(radioModule.updateReady)        {            radioModule.updateReady = false; //Clear flag            //do some intensive stuff        }    }}/** * Callback when a radio module reports new data * @param m Radio module with new data */@Overrideprotected void onModuleStatusReport(RadioModule m){    if(mState == JOB_STATE_RUNNING)    {        //The below comments spawn a new thread on each feedback...         //I want to get around this        //ModuleFeedbackTask moduleFeedbackTask = new ModuleFeedbackTask(m);        //moduleFeedbackTask.setPriority(Thread.NORM_PRIORITY);        //moduleFeedbackTask.setName("ModFbTask");        //moduleFeedbackTask.start();        super.onModuleStatusReport(m);    }}
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

有很多方法可以解决这个问题,但我建议BlockingQueue在工作线程和任何其他可以发出信号以执行其任务的线程之间使用共享。worker 的任务被设置在一个循环中,在循环的顶部它尝试take()从队列中获取一个对象。这将阻塞,直到某个其他线程将一个对象排入队列,该对象构成了信号。

这种方法的一些优点包括:

  • 您可以轻松自然地一次将多个信号排队,这样如果在发布信号时工作人员实际上正在工作,则该信号不会丢失;

  • 您可以通过入队对象向工作人员传达信息,例如任务参数或退出信号而不是执行任何任务;

  • 您有一个内置选项可以在接收信号时使用超时;和

  • 所有BlockingQueue实现都是线程安全的,因此您无需担心实现自己的同步。

示例

public OnDemandTask implements Runnable {

    private final BlockingQueue<?> signalQueue;


    public FeedbackTask(BlockingQueue<?> signalQueue) {

        this.signalQueue = signalQueue;

    }


    @Override

    public void run() {

        try {

            while (true) {

                // blocks until an object becomes available from the queue

                // may throw InterruptedException

                signalQueue.take();


                performTask();

            }

        } catch (InterruptedException ie) {

            // we've broken out of the loop; nothing further to do

        }

    }


    private performTask() {

        // ...

    }

}


查看完整回答
反对 回复 2022-06-30
  • 1 回答
  • 0 关注
  • 129 浏览

添加回答

举报

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