Java线程 - 这是正确使用synchronized

时间:2013-11-11 20:20:12

标签: java multithreading bluetooth

我在 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 变量只会在主线程中更改,是否需要同步。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

简单的答案:mConnected只能在同步块中访问。您显示的代码很好,但更改值的代码也必须在同步块中。原因是otherwize Java没有义务让一个线程看到另一个线程所做的更改。在这种情况下,你不真的需要同步块来同步任何东西,只是为了强制每个线程看到对方的变化。

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

因此,请保留示例中的同步块(对于openReadingThread而言,比mConnected更多),并在设置mConnected make mConnected volatile时使用另一个。易失性字段很昂贵,但是同步块也是如此,特别是当您不需要同步但只在线程中显示字段时。我会说如果变化很少,你会仔细阅读上面的代码,跳过volatile并使用第二个同步块。但是如果你经常改变这个值,那就选择一个volatile mConnected并且只有一个同步块(你的例子中的那个,现在只需要该方法,而不是mConnected)。

Addtional:我正打算告诉Philipp Sander他说“这个”是错的,但是,乍一看,他不是;它需要修复。