Android Activity onCreate方法中调用的同步方法

4
以下情况是设计不良还是我忽略了重要的东西?
以下是代码:
public class MainActivity extends AppCompatActivity … {

  …

  @Override
  public void onCreate(Bundle savedInstanceState){
     …
     buildGoogleApiClient();
  }

  /**
   * Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
   */
    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
}

为什么buildGoogleApiClient只会从onCreate内部调用,但却需要synchronized
我知道这样做不会有害,但这并不是问题的重点。我需要知道的是:为什么需要这样做? 编辑 完整代码源: https://github.com/googlesamples/android-play-location/blob/master/BasicLocationSample/app/src/main/java/com/google/android/gms/location/sample/basiclocationsample/MainActivity.java

谢谢您的回复。但不幸的是,我不理解您的回应。谢谢。 - Nouvel Travay
根据该方法当前的使用情况,我会说不需要,实际上我不知道为什么会有多个线程试图在一个应用程序上构建相同的API客户端。 - CodeCody
这段内容来自 http://developer.android.com/training/location/retrieve-current.html。他们的工程师应该是一流的,他们建造了安卓,所以...值得思考这里发生了什么。 - Nouvel Travay
1个回答

3
在这种情况下,synchronized会锁定对象在调用期间。如果其他方法也声明了synchronized,那么其中一个将在任何给定时间执行。例如,如果从另一个线程的同步方法中访问mGoogleApiClient,则同步将确保另一个线程看到完全构造的对象或空引用。
即使如此,您仍然可以认为这是一种不良实现。更好的方法是每个方法都同步于一个私有对象,以便类外的代码不会意外锁定对象并导致意外行为。另一方面,可以认为synchronized方法更适合示例,因为代码行数较少且可以明显地看出同步应用于整个方法。
在这种特定情况下,volatile可能有效,尽管我不确定如何在生成器模式中运行。
无论如何,您需要了解代码的...部分才能确定是否需要同步。

谢谢您的回复。我添加了...来截取代码。源代码在https://github.com/googlesamples/android-play-location/blob/master/BasicLocationSample/app/src/main/java/com/google/android/gms/location/sample/basiclocationsample/MainActivity.javal。您似乎在一般情况下解释并发性。但是关键字在提供的上下文中如何应用? - Nouvel Travay
我看到了几种可能性:(1)如果像 onConnectionSuspended() 这样的回调可以在任意线程上调用,则同步可能会有用。当然,这些回调不是同步的,所以不是这个原因。(2) 同步方法为 protected,因此开发人员可能预期它将在一个派生类中使用,该类也是多线程的。(3) 它从其他项目中复制并粘贴,而在那个项目中它实际上是必要的。无论哪种情况,如果 mGoogleApiClient 仅从一个线程访问,则不需要同步访问它。 - fadden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接