0

Ok, so I am little perplexed as to why synchronized was used in the line marked below.

To me, you only use synchronized where a block of code will potentially be accessed by multiple threads however this code is only ever called from this thread in its run method.

An instance of mConnectThread is declared as a field at the very start of the class.

public class BluetoothChatService {

// Member fields   
private ConnectThread mConnectThread;

Any ideas?

/**
 * 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);
        }
    }
}

Cheers

mgibson
  • 6,103
  • 4
  • 34
  • 49

1 Answers1

1

You can have multiple ConnectThread objects going simultaneously, which means multiple threads in the same run method(technically, copies of the run method, but the same code), though they'll all have access to different member variables. The synchronized block is syncing on an external object, so I suspect there's a synchronized block somewhere else in the program that looks like

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

Edit:

To clarify, they aren't preventing two threads from accessing the same block of code, they're preventing two threads from accessing the same variable from different sections of code.

Thomas
  • 5,074
  • 1
  • 16
  • 12
  • There is no `synchronized (BluetoothChatService.this)` that mentions `mConnectThread` at all from what I can see, any other synchronized block seems to have its own distinct function. However, the rest of what you said makes a lot of sense, Cheers! – mgibson Jan 30 '13 at 17:05
  • If those other methods are in the BluetoolCharService class, this block will sync with them. See [this answer](http://stackoverflow.com/questions/1149928/what-is-the-difference-between-a-synchronized-method-and-synchronized-block-in-j) – Thomas Jan 30 '13 at 17:08
  • But one further question, this may be a bit vague.. How is that syncronized command (mConnectThread = null) related to the fact mConnectThread is an instance of ConnectThread. (The thread that contains the run method shown) Should you always synchronize a reference to an instance of a thread inside the code of that Thread class? – mgibson Jan 30 '13 at 17:13
  • If I understand the question correctly, it's a coincidence. The usage of synchronized blocks would be used the same if mConnectThread was an instance of something else that different threads were using/setting to null. – Thomas Jan 30 '13 at 22:25