如何在主线程和后台线程之间安全地共享数组

时间:2016-10-31 08:28:48

标签: android multithreading

我在MyApplication类中有一个数组(myData),我用它来使用BaseAdapter在MainActivity中填充列表视图。

现在我需要对数组进行一些处理,这需要更新数组项。如何让后台线程线程安全地更新数组,同时在主线程中显示数组的内容?

部分 MyApplication.java

public class MyApplication extends Application{

    private List<MyData> myData;
    private MyApplication instance;

    public static synchronized MyApplication getInstance(){
        return instance;
    }

    public List<MyData> getMyData(){
        return myData;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        myData = new ArrayList<>();
    }    
}

部分 MainActivity.java

public class MainActivity extends AppCompatActivity{

    private ListView myList;
    private MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        myList = (ListView)view.findViewById(R.id.my_list);
        myAdapter = new MyAdapter(this);
        myAdapter.setData(MyApplication.getInstance().getMyData());
        myList.setAdapter(myAdapter); 
        //myList also listens to onItemClick
    }
}

部分 MyAdapter.java

public class MyAdapter extends BaseAdapter{

    private List<MyData> data;
    private Context context;

    public MyAdapter(Context context){
        this.context = context;
    }

    public void setData(List<MyData> data){
        this.data = data;
    }
}

部分 MyIntentService.java

public class MyIntentService extends IntentService{
    @Override
    protected void onHandleIntent(Intent intent)
        List<MyData> data = MyApplication.getInstance().getMyData();
        //beside re-arranging, there might also be an update and delete item
        if(updated){
            //notify broadcast receiver in MainActivity that array has been updated
            LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ARRAY_UPDATED));
        }
    }
}

1 个答案:

答案 0 :(得分:0)

有两种完全不同的情况,取决于你的意思&#34;更新&#34;。

在使用列表时更改列表内容:

如果通过&#34;更新&#34;你的意思是你想在BG线程的列表中添加/删除元素,而在UI线程上同时读取相同的列表,那么List接口的线程安全实现就足够了。查看CopyOnWriteArrayList

的文档

更改阵列中的特定项目时使用

如果通过&#34;更新&#34;你的意思是你想要改变特定列表的元素(例如myData.get(0).setPropery("some property")),那么情况就更复杂了。为了安全地执行这样的动作,包含列表的每个特定对象类型的实现必须是线程安全的。最安全的方法是将List的线程安全实现与MyData的线程安全实现相结合。