简体   繁体   中英

“synchronized” method vs. “synchronized (Class.class)”

I'm reading the BluetoothChatService.java file from Android sample and one thing in particular confuses me.

  • There are multiple locations in which a method is accessing a static member and it is defined as synchronized .
  • In another section, the same static member is being accessed but the Class-Level synchronization is used instead of a synchronized method.
  • And also there is another method which is not synchronized but uses synchronized(this) instead.

Can somebody explain the reason for using different techniques?

Source code is available at BluetoothChatService.java and here are some snippets that I was talking about:

private int mState;

// Constants that indicate the current connection state
public static final int STATE_NONE = 0;      
public static final int STATE_LISTEN = 1;     
public static final int STATE_CONNECTING = 2; 
public static final int STATE_CONNECTED = 3;

synchronized method :

public synchronized void start() {
             ...
        setState(STATE_LISTEN);
             ...
}

synchronized block (class-level) :

if (socket != null) {
    synchronized (BluetoothChatService.this) {
        switch (mState) {
            case STATE_LISTEN:
            case STATE_CONNECTING:
            // Situation normal. Start the connected thread.
            connected(socket, socket.getRemoteDevice(),
            mSocketType);
            break;
            case STATE_NONE:
            case STATE_CONNECTED:
            // Either not ready or already connected. Terminate new socket.
            try {
                socket.close();
                } catch (IOException e) {
                Log.e(TAG, "Could not close unwanted socket", e);
            }
            break;
        }
    }
}

synchronized (this) :

public void write(byte[] out) {
        // Create temporary object
        ConnectedThread r;
        // Synchronize a copy of the ConnectedThread
        synchronized (this) {
            if (mState != STATE_CONNECTED) return;
            r = mConnectedThread;
        }
        // Perform the write unsynchronized
        r.write(out);
    }

In all cases lock is taken on current instance of BluetoothChatService .

1- synchronized (BluetoothChatService.this)

is used when code is written inside another class, can be an anonymous class inside BluetoothChatService . In order to refer to instance of BluetoothChatService .

2- synchronized (this)

is used inside any member function of BluetoothChatService. Which points to it's instance.

3- synchronized void start()

is used when entire method need to be synchronized. it is equivalent to

void start(){ synchronized (this){

In first 2 cases other parts of the function(not inside synchronous block), do not require to be thread safe and putting a synchronized keyword before function name would make entire function thread safe, and as a result will make your app necessarily slow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM