java - Android - BluetoothChat 示例 - 为什么他们在这种情况下使用同步?

标签 java android multithreading deadlock synchronized

好吧,我对为什么在下面标记的行中使用同步有点困惑。

对我来说,只有在代码块可能被多个线程访问的情况下才使用同步,但是该代码只能在其 run 方法中从该线程调用。

mConnectThread 的实例在类的最开始被声明为一个字段。

public class BluetoothChatService {

// Member fields   
private ConnectThread mConnectThread;

有什么想法吗?

/**
 * This thread runs while attempting to make an outgoing connection
 * with a device. It runs straight through; the connection either
 * succeeds or fails.
 */
private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;
    private String mSocketType;

    public ConnectThread(BluetoothDevice device, boolean secure) {
        mmDevice = device;
        BluetoothSocket tmp = null;
        mSocketType = secure ? "Secure" : "Insecure";

        // Get a BluetoothSocket for a connection with the
        // given BluetoothDevice
        try {
            if (secure) {
                tmp = device.createRfcommSocketToServiceRecord(
                        MY_UUID_SECURE);
            } else {
                tmp = device.createInsecureRfcommSocketToServiceRecord(
                        MY_UUID_INSECURE);
            }
        } catch (IOException e) {
            Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
        }
        mmSocket = tmp;
    }

    public void run() {
        Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
        setName("ConnectThread" + mSocketType);

        // Always cancel discovery because it will slow down a connection
        mAdapter.cancelDiscovery();

        // Make a connection to the BluetoothSocket
        try {
            // This is a blocking call and will only return on a
            // successful connection or an exception
            mmSocket.connect();
        } catch (IOException e) {
            // Close the socket
            try {
                mmSocket.close();
            } catch (IOException e2) {
                Log.e(TAG, "unable to close() " + mSocketType +
                        " socket during connection failure", e2);
            }
            connectionFailed();
            return;
        }

        /********* THIS BIT OF CODE BELOW IS WHAT I AM ASKING ABOUT **********/

        // Reset the ConnectThread because we're done
        synchronized (BluetoothChatService.this) {
            mConnectThread = null;
        }

        /**********************************^^*********************************/

        // Start the connected thread
        connected(mmSocket, mmDevice, mSocketType);
    }

    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
        }
    }
}

干杯

最佳答案

您可以让多个 ConnectThread 对象同时运行,这意味着同一 run 方法中的多个线程(从技术上讲,是 run 方法的副本,但代码相同),尽管它们都可以访问不同的成员变量。同步块(synchronized block)正在外部对象上同步,因此我怀疑程序中其他地方有一个同步块(synchronized block),看起来像

synchronized (BluetoothChatService.this)
{
  if (mConnectThread != null)
    do some work that would throw NPE without the check.
}

编辑:

需要澄清的是,它们并不是阻止两个线程访问同一代码块,而是阻止两个线程从不同的代码部分访问同一变量。

关于java - Android - BluetoothChat 示例 - 为什么他们在这种情况下使用同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14609040/

相关文章:

java - Excel 电子表格中的字符编码(以及使用什么 Java 字符集对其进行解码)

java - 用于 Java 的日志解析器

c# - 在线程之间共享字典中的数据

multithreading - 常见的Lisp : Run function in the background

java - Java中不同进程中启动线程

java - 如何在不使用类名的情况下调用此方法

java - lucene 在查询中获取匹配项

java - 从 Recycler View 中删除条目时出现问题

Android 运动布局 : Android resource linking failed

android - "App Engine Connected Android Project"不可用