title: "synchronized" method vs. "synchronized (Class.class)"
body: <p>I'm reading the <code>BluetoothChatService.java</code> file from Android sample and one thing in particular confuses me. </p>
  
  <ul>
  <li>There are multiple locations in which a method is accessing a <strong>static member</strong> and it is defined as <strong>synchronized</strong>. </li>
  <li>In another section, the same static member is being accessed but the
  Class-Level synchronization is used instead of a synchronized method.</li>
  <li>And also there is another method which is not synchronized but uses <code>synchronized(this)</code> instead.</li>
  </ul>
  
  <p>Can somebody explain the reason for using different techniques? </p>
  
  <p>Source code is available at <a href="https://android.googlesource.com/platform/development/+/25b6aed7b2e01ce7bdc0dfa1a79eaf009ad178fe/samples/BluetoothChat/src/com/example/android/BluetoothChat/BluetoothChatService.java" rel="nofollow">BluetoothChatService.java</a> and here are some snippets that I was talking about:</p>
  
  <pre><code>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;
  </code></pre>
  
  <p><strong>synchronized method</strong>:</p>
  
  <pre><code>public synchronized void start() {
               ...
          setState(STATE_LISTEN);
               ...
  }
  </code></pre>
  
  <p><strong>synchronized block (class-level)</strong>:</p>
  
  <pre><code>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;
          }
      }
  }
  </code></pre>
  
  <p><strong>synchronized (this)</strong>:</p>
  
  <pre><code>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);
      }
  </code></pre>