2011-07-27 24 views
5

我有一个线程锁定了在我的Android应用程序仍有一些未知的原因,每当我试图杀死从线程A线程B的一个问题(通常,有时它的工作)。我猜想这是因为我的一些方法在线程间进行调用而未被同步。我制作了取消方法和许多基本上是事件处理程序同步的方法,并使几个共享变量变得不稳定并且一切正常。在Java中同步声明方法进行权衡?

我不知道是哪20个奇挥发性/同步声明我实际上增加解决了这个问题,这让我开始思考“我应该在乎吗?它的工作原理不惹它!”中

所以,我的问题是:是否与声明同步的方法或原挥发掉相关的任何交易?如果不需要这些声明,是否有任何理由避免这些声明?

编辑
的问题线程(S)是接收/发送数据流,这样的AsyncTask和其他辅助线程型的解决方案并不能很好地工作蓝牙连接。它们设计用于执行有限的任务,并在完成时终止。一些像ASyncTask一样,也增加了很多简单的杀死应用程序的开销。对于像这样持续运行的线程,使用线程仍然是最好的方法。

我使用的是Android Service生成和管理线程,所以我下面在这方面Android的设计范例。

+0

有一个(小?)固有的性能损失。很难说出“锁定线程的问题”是什么(轮询非易失性成员字段?),但是自由添加“synchronized”听起来像是一个解决死锁的好方法,并且您怎么知道您的应用程序是没有比赛条件?最大的问题是你在线程之间有很多共享状态 - 你需要决定什么需要共享,确保共享状态是线程安全的(尽可能地提供不可变的帮助),并决定线程如何通信(Handler/ConcurrentLinkedQueue/LinkedBlockingQueue?)。 –

回答

-1

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

+0

我了解ASyncTask,但这是一个需要不断运行的线程的蓝牙通信应用程序。 ASyncTask适用于将来在有限时间结束的单一任务,而不是稳定的连接。 ASyncTask很棒,但它不是一个神奇的子弹。 – CodeFusionMobile

+0

对不起,我不知道你在哪里使用它,但基于'20奇怪volatile/synchronized'对于Java程序来说仍然非常复杂。 – user802421

+2

对于背景蓝牙通信,您不应该将其作为正在进行的服务吗?让Android系统管理您的服务线程,并让您的应用程序与服务对话。 – fluffy

4

根据我的经验,通过使用同步(对象){...}访问特定对象,尽可能在更细粒度的级别上执行锁定通常更简单,而且通常更具性能。另外,如果您必须同时获得多个锁,请始终确保您始终以相同的顺序获取它们。

静态方法都有自己的古怪担心的块;一个同步实例方法将只与该实例同步,而不是作为整体的类同步,因此如果需要在实例方法中同步两者,则需要执行类似synchronized(this.class)的操作。 。}同样,尽管如果你正在应用上面的内容,那么你真的只是在你用特定方法访问的静态字段上进行synchronized()。

另外需要说明的是,一般情况下,您不希望产生自己的线程,而应该使用系统预先存在的线程管理机制(例如ThreadPoolExecutor用于正在进行的工作队列或AsyncTask用于异步UI更新) 。 ThreadPoolExecutor往往更具性能(并且可以更好地利用多核设备),但是如果要向UI执行操作,则必须做一些额外的工作;另一方面,AsyncTask往往会慢一点,也更重一些,但它也会在UI线程中运行onPostExecute回调。

+0

所有这些方法(ThreadPool,ASyncTask等)都设计用于运行任务或某种形式的重处理,这些处理将在作业完成时终止。我正在管理一个活动的蓝牙连接并发送数十个不同的数据包,并监视大量的连接状态和变量。对于像这样的非终止进程,ASyncTask和工作线程不是正确的选择。 – CodeFusionMobile

+0

好的。我的第三段更多的是作为一般的经验法则,而不是特定于编辑过的您的问题,但它仍然是一般要记住的事情。 – fluffy