我在 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 变量只会在主线程中更改,是否需要同步。
答案 0 :(得分:1)
在这种情况下,您创建的每个线程都有自己的锁(对象本身) 你应该使用静态(如类)来锁定。
答案 1 :(得分:1)
简单的答案:mConnected只能在同步块中访问。您显示的代码很好,但更改值的代码也必须在同步块中。原因是otherwize Java没有义务让一个线程看到另一个线程所做的更改。在这种情况下,你不真的需要同步块来同步任何东西,只是为了强制每个线程看到对方的变化。
不太简单:这几乎是制作mConnected volatile
的好例子。然后,您可以跳过同步块。但是那时可以同时在openReadingThread中获得两个线程。
因此,请保留示例中的同步块(对于openReadingThread而言,比mConnected更多),并在设置mConnected 或 make mConnected volatile时使用另一个。易失性字段很昂贵,但是同步块也是如此,特别是当您不需要同步但只在线程中显示字段时。我会说如果变化很少,你会仔细阅读上面的代码,跳过volatile并使用第二个同步块。但是如果你经常改变这个值,那就选择一个volatile mConnected并且只有一个同步块(你的例子中的那个,现在只需要该方法,而不是mConnected)。
Addtional:我正打算告诉Philipp Sander他说“这个”是错的,但是,乍一看,他不是;它需要修复。