何时使用在新线程中创建的处理程序是否安全?

时间:2012-08-12 22:34:52

标签: android multithreading thread-safety handler

我有一些代码来创建一个新线程,然后是该线程中的处理程序和循环器。然后调用线程可以发布到这个处理程序:

class MyClass {

    Handler mHandler = null;
    Thread mThread = null;

    MyClass() {
        mThread = new Thread() {
            public void run() {
                Looper.prepare();
                mHandler = new Handler();
                Looper.loop();
            }
        };

        mThread.start();

        /* ... */

        mHandler.post(...);
    }
}

此代码几乎直接来自文档中的示例。但我无法理解它是如何正确的。因为mHandler在子线程内初始化,所以不能保证何时发生。什么阻止此代码在最后一行中发布到空处理程序?

如果此代码不正确,那么以同步方式在新创建的线程上创建处理程序的方法是什么?

3 个答案:

答案 0 :(得分:1)

最简单的方法是使用HandlerThread:

class MyClass {

    final Handler mHandler = null;
    final HandlerThread mThread = null;

    MyClass() {
        mThread = new HandlerThread("...");
        mThread.start();
        mHandler = new Handler(mThread.getLooper());

        /* ... */

        mHandler.post(...);
    }
}

这会使同步问题发生短路,因为looper是在Thread.start()中创建的,因此处理程序可以链接到父线程中的looper。

答案 1 :(得分:0)

我会用这种方式来完成这项工作,我认为这不是最好的,只是想知道更好的想法,所以我把它扔出去。

mThread = new Thread() {

    public void run() {
        Looper.prepare();
        mLooper = Looper.myLooper();
        mHandler = new Handler();
        Looper.loop();
        }
    };

mThread.start();

......
timeout = 0;
mHandler2 = new Handler ();
DetectHandlerIsReady detect = new DetectHandlerIsReady ();
detect.run ();

class DetectHandlerIsReady implements Runnable {
    public void run ()
    {
         if (mHandler != null) { 
              mHandler.post (....);
         } else if (timeout <= 30) {
              timeout++;
              mHandler2.postDelay (detect, 1000);
              return;
         } 

         // timeout, and mHandler is not ready yet
    }
}

答案 2 :(得分:0)

在你的例子中,什么是Looper(它在哪里声明)?线程是轻量级进程,它们在进程中创建并共享其数据。一个线程可以反过来创建一个新线程(子线程),反过来可以创建另一个线程和s.o ..   您可能需要查看mutexes, locks and semaphores

您可以使用标记(对一组线程可见)来确定它们的行为。