多线程中的坑(UI线程等待其他线程同步,可用handlerThread解决)

参考文章:
为什么wait(), notify(), notifyAll()必须要在synchronized方法/块
HandlerThread的使用以及原理

问题:UI线程创建workerThread来处理事务,UI线程首先给一些资源给workerThread然后workerThread处理完返回给UI线程显示,UI中需要创建handler来处理UI发来的资源。正常实现后发现UI发送消息的时候handler为null,代码中UI线程先调用workerThread.start(里面马上创建handler),然后UI线程接着用handler,但实际运行的时候后者先执行了。

解决办法:锁。
UI线程中如果先执行,获得锁,就会放弃,wokerThread得到锁,然后创建handler,释放锁再继续执行。
wokerThread先执行也是可以的。

UI线程

          Object lock = new Object();
        // 初始化识别引擎
        synchronized(lock) {
            try {
                lock.wait();
            }catch (Exception e){
                e.printStackTrace();
            }

            //执行handler相关的内容
        }

workerThread

synchronized (lock) {
创建handler
lock.notify();
}
  • 用HandlerThread解决更方便

下面的语句是在UI线程中执行的,虽然调用了Handler生成,但由于输入参数Looper是新建线程的,所以会在Handler会在新建线程中运行。那么这里的Handler会在UI使用之前生成,新建线程也不用想办法去生成后返回handler,但这里还有一个问题,由于Loop是在新线程中生成的,可能UI线程先执行Loop还没有新建好呢!!但HandlerThread内部已经帮我们搞定了,也是跟上面差不多的做法。在getLoop的时候UI线程会等待Loop生成好再执行。

    private void initThread()
    {
        mHandlerThread = new HandlerThread("check-message-coming");
        mHandlerThread.start();

        mThreadHandler = new Handler(mHandlerThread.getLooper())
        {
            @Override
            public void handleMessage(Message msg)
            {
                update();//模拟数据更新

                if (isUpdateInfo)
                    mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
            }
        };

    }

你可能感兴趣的:(多线程中的坑(UI线程等待其他线程同步,可用handlerThread解决))