java - 使用处理程序访问共享数据

标签 java android multithreading android-handler

在我的 Android 项目中,我有一个类,在其中注册了 BroadcastReceiver:

public MyClass {
     private MyData mData;

     public MyClass(Context context) {
        mData = GET_PERSISTED_DATA(); 
        //code to register receiver
        ...
        context.registerReceiver(myReceiver, filter);
     }

     public void accessData() {
        //Code to access mData
        ...
     }

     private BroadcastReceiver myReceiver=  new BroadcastReceiver() {

        @Override
        public void onReceive (Context context, Intent intent) {
                    //This is called in main UI thread
                    accessData();
             }

}

如上所示,在myReceiveronReceive()中,它调用accessData()方法来访问mData. 但是,还有另一个工作线程(主线程除外)也可以调用accessData()方法。这意味着它线程安全。

Handler从消息队列中一一处理消息,我可以使用 Handler通过以下方式使上述情况线程安全?或者有更优雅的方式吗?

public MyClass {
         private MyData mData;
         private Handler mHandler;

         public MyClass(Context context) {
            mData = GET_PERSISTED_DATA(); 
            //code to register receiver
            ...
            context.registerReceiver(myReceiver, filter);
            mHandler = new MyHandler();
         }

         public void accessData() {
            mHandler.sendMessage(mHandler.obtainMessage(1));
         }

         private class MyHandler extends Handler() {
             @Override
             void handleMessage(Message msg){
                 if(msg.what == 1){
                    //Code to access mData
                     ...
                 }

             }
         }

         private BroadcastReceiver myReceiver=  new BroadcastReceiver() {

            @Override
            public void onReceive (Context context, Intent intent) {
                        //This is called in main UI thread
                        accessData();
                 }

    }

通过以上方式使用处理程序,我现在线程安全吗?

最佳答案

如果 accessData() 方法很快,那么只需将其声明为同步即可。如果它是长时间运行的,那么,除了声明它是同步的之外,当从 onReceive() 调用时,还要注意它正在运行的线程,因为默认情况下 onReceive() 是在主(UI)线程上调用的,并且该线程不能被长期占用。其他地方描述了如何在主线程之外执行长时间运行的工作。

附加: 您的实现可能会起作用,但有一些陷阱:实际执行 accessData() 引起的工作的线程是执行 MyClass 构造函数的线程。首先,这是一个糟糕的设计:初始化线程可能会改变,并且程序可能会停止工作,因为新线程可能没有Looper。然后,初始化线程是 UI 线程,这意味着即使工作线程也将工作委托(delegate)给 UI 线程,而通常 UI 线程必须从任何非 UI 工作中释放出来。

处理程序和循环器不是通用方法,应尽可能使用。首先学习多线程编程的基础知识,您会发现没有它们您也可以生活。

关于java - 使用处理程序访问共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24478423/

相关文章:

Java Collections 使用正则表达式过滤元素

java - 我该如何修复这段代码? (if 语句)

java - 如何在不加载内存中所有文件 jar 的情况下检索 jar 中的方法列表?

Android - 推送通知 - 答案

android如何使用自定义 ListView 动态绑定(bind)复选框

java - 列出三个可以点击播放的声音(ogg)文件?

java - 如何在超过一定时间后立即停止线程?

android - 使用 Handler 从线程更新 UI 时出错

java - 重命名类时应该对 javadoc 进行哪些更改?

Java多线程性能