在java中同步声明方法进行权衡?

时间:2011-07-27 18:31:12

标签: java android multithreading volatile synchronized

每当我试图从线程A中杀死线程B时,我的Android应用程序中出现了一些线程仍然未知原因,我遇到了一个问题(通常,有时它会工作)。我猜这是因为我的一些方法是在没有同步的情况下跨线程进行调用。我创建了取消方法和许多基本上与事件处理程序同步的方法,并使一些共享变量变得易变,一切正常。

我不知道在我添加的20个奇怪的易失/同步声明中哪个实际上解决了这个问题,这让我想到“我应该关心吗?它的工作原理并没有弄乱它!”

所以,我的问题是:声明同步方法或原始易失性是否有任何权衡?如果不需要这些声明,有没有理由避免这些声明?

修改
所讨论的线程是接收/发送流数据的蓝牙连接,因此ASyncTask和其他工作线程类型解决方案不能很好地工作。它们设计用于执行有限任务并在完成后终止。有些像ASyncTask一样,也增加了很多开销,只会导致应用程序死亡。对于像这样连续运行的线程,使用Thread仍然是最好的方法。

我正在使用android Service来生成和管理线程,所以我在这方面遵循Android设计范例。

2 个答案:

答案 0 :(得分:4)

根据我的经验,通过使用synchronized(object){...}来访问特定对象,以尽可能细粒度的级别进行锁定通常更容易且通常更高效。此外,如果您必须同时获取多个锁,请始终确保始终以相同的顺序获取它们。

静态方法有其自身的一些奇怪的担忧;一个synchronized实例方法只会同步到那个实例,而不是整个类,所以如果你需要在一个实例方法中同步这两个,你需要做一些像synchronized(this.class){.. 。}同样,虽然如果您正在应用上述内容,实际上您只是对您在特定方法中访问的静态字段执行synchronized()。

另外请注意,通常您不希望生成自己的线程,而是应该使用系统预先存在的线程管理机制(例如用于正在进行的工作队列的ThreadPoolExecutor或用于异步UI更新的AsyncTask)。 ThreadPoolExecutor往往性能更高(并且可以更好地利用多核设备),但如果它要向UI做一些事情,你必须做一些额外的工作;另一方面,AsyncTask往往更慢,更重量级,但它也在UI线程中运行onPostExecute回调。

答案 1 :(得分:-1)

如果它工作暂时不修复它:),但对于下一个项目,你应该考虑使用AsyncTaskDev Guide。我不认为性能影响不是Android环境中真正关注的问题,但复杂性,可读性和未来可维护性可能是一个问题(取消/终止线程,许多共享变量)。