0

我正在尝试为Android应用程序同步两个代码块。滥用同步?

第一个块使用AsyncFacebookRunner为用户的兴趣提出请求(如果有的话)。

如果发现兴趣,则该用户的成员变量将使用Facebook JSON响应中的兴趣填充。

第二个代码块通过查看该成员变量来检查用户实际上是否有兴趣。如果有兴趣,则会执行几个额外的代码行。

synchronized(this) 
{ 
    if ((friend.getmActivities().length() == 0) && (friend.getmInterests().length() == 0)) 
     friend.requestInterests(mFacebook); // Get that friend's Facebook activities and interests. 
} 

synchronized(this) 
{ 
    if ((friend.getmActivities().length() == 0) && (friend.getmInterests().length() == 0)) 
    { 
     final AlertDialog alertDialog = new AlertDialog.Builder(mContext).create(); 
     alertDialog.setTitle("Sorry..."); 
     alertDialog.setMessage("Your friend isn't sharing their interests."); 
     alertDialog.setButton("Go Back", new DialogInterface.OnClickListener() { 

      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       alertDialog.dismiss(); 
      } 
     }); 

     alertDialog.show(); 
    } 
} 

我希望第二个模块等到friend.requestInterests()完成后再执行。

编辑:我结束了重构我的代码,以利用亚军的onComplete方法。这一切都是在我修改我的程序结构并不得不改变一切的时候出现的。感谢所有的帮助。

+1

AysncFacebookRunner *应该*支持回调。使用这些(如果它不,...找到一个更好的图书馆?:-)。然后,这只是对“完成”事件作出反应的问题,非常类似于正常的按钮单击或不按钮。根据确切的细节(例如,线程是什么线程),可能仍然需要“同步”。但是,这是一个糟糕的错误使用,可能甚至不能做到所期望的。考虑其他“基元”,例如互斥或信号量用于“非范围”资源控制。 (另请参阅期货等) – 2011-05-18 22:44:13

+0

这是事实。不过,我宁愿在不使用回调的情况下执行此操作。我将不得不相当大地修改我的代码的结构以利用onComplete。 – SemperFly 2011-05-18 22:50:56

回答

1

我希望第二个模块等到friend.requestInterests()完成后再执行。

的JVM确保两个块不会在同一时间执行为这个相同的实例。

如果另外要确保第二块只得到第一运行后运行,那么你可以使用这个状态变量和wait/notify电话做。但更好的方法是使用其中一个同步类,如CountDownLatch;例如

private CountDownLatch latch = new CountDownLatch(1); 

... 

synchronized(this) { 
    // do first actions 
} 
this.latch.countdown(); 

.... 

this.latch.await(); 
synchronized(this) { 
    // do second 
} 

事实上,如果这些地方的相关对象状态访问和更新的唯一的地方,你应该能够与​​块进行分配。拨打countdownawait将提供必要的“前来”关系以确保正确的同步。


然而,@ PST的评论提出了一个点,有可能是一个更好的方式来做到这一点使用您的代码使用Facebook的库框架的API。