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

Java 使用处理程序访问共享数据,java,android,multithreading,android-handler,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(myRece

在我的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();
             }

}
如上所述,在
myReceiver
onReceive()
中,它调用
accessData()
方法来访问
mData
但是,另一个工作线程(主线程除外)也可以调用
accessData()
方法。这意味着它不是线程安全的

由于处理消息队列中的一个接一个的消息,我是否可以使用以下方式使上述案例线程安全?还是有更优雅的方式

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构造函数的线程。首先,这是一个糟糕的设计:初始化线程可能会改变,程序可能会停止工作,因为新线程可能没有活套。然后,初始化线程是UI线程,这意味着即使工作线程也将工作委托给UI线程,而通常UI线程必须从任何非UI工作中释放出来


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

谢谢,但我也想知道,按照我发布的方式使用处理程序是线程安全的吗?