滥用同步?

时间:2011-05-18 22:26:53

标签: java android multithreading facebook-graph-api synchronized

我正在尝试为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 个答案:

答案 0 :(得分:1)

  

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

JVM确保两个块不会同时为 this 的相同实例执行。

如果另外想要确保第二个块只能在第一个运行之后运行,那么你可以使用状态变量和{{1 } / wait来电。但更好的方法是使用其中一个同步类CountDownLatch; e.g。

notify

实际上,如果这些是访问和更新相关对象状态的唯一位置,那么您应该可以省去private CountDownLatch latch = new CountDownLatch(1); ... synchronized(this) { // do first actions } this.latch.countdown(); .... this.latch.await(); synchronized(this) { // do second } 块。对synchronizedcountdown的调用将提供必要的“先到先得”关系,以确保正确同步。


但是,@ pst的评论提出了一个更好的方法,即使用您的代码使用的Facebook库框架的API来实现这一点。