0

我在Android上使用蓝牙;简而言之,如果套接字当前未连接,我只想打开一个新线程来接收- 我正在使用布尔值进行测试。

所以:

class Main {

   protected boolean mConnected;

   public void startClientConnection() {
      ClientRunnable thread = new ClientRunnable() {
         @Override public void manageSocket(BluetoothSocket pSocket) {
            synchronized (this) {
               if (!mConnected) openReadingThread(pSocket);
            } // end synchronized()
         } // end manageSocket()
      }; // end ClientRunnable
   } // end startClientConnection()

} // End CLASS

编辑: 本质上,我需要知道的是,因为 Runnable 将在单独的线程上运行,但mConnected变量只会在主线程中更改,是否需要同步。

4

2 回答 2

1

在这种情况下,您创建的每个线程都有自己的锁(对象本身),您应该使用静态的东西(如类)作为锁。

于 2013-11-11T20:36:59.997 回答
1

简单的答案:mConnected 只能在同步块中访问。您显示的代码很好,但是您更改值的代码也必须在同步块中。这样做的原因是,otherwize Java 没有义务让一个线程看到另一个线程所做的更改。在这种情况下,您实际上并不需要同步块来同步任何内容,只需强制每个线程查看其他线程的更改。

不太简单:这几乎是制作 mConnected 的好案例volatile。然后,您可以跳过同步块。但是有可能同时在 openReadingThread 中获得两个线程。

因此,请在您的示例中保留同步块(对于 openReadingThread 而言比对于 mConnected 更多),并且在设置 mConnected使 mConnected 易失性时使用另一个。易失性字段很昂贵,但同步块也是如此,特别是当您不需要同步但只使字段跨线程可见时。我会说如果更改很少并且您通过上面的代码进行了很多,请跳过易失性并使用第二个同步块。但是,如果您更改了很多值,请使用 volatile mConnected 并且只有一个同步块(您的示例中的那个,现在只需要用于方法,而不需要用于 mConnected)。

补充: 我正要告诉菲利普·桑德,他对“这个”的看法是错误的,但回头一看,他不是;它需要修复。

于 2013-11-11T21:16:25.873 回答