开发者

Misuse of synchronized?

开发者 https://www.devze.com 2023-03-06 17:32 出处:网络
I\'m trying to synchronize two blocks of code for an Android app. The first block uses an AsyncFacebookRunner to make a request for a user\'s interests, if any.

I'm trying to synchronize two blocks of code for an Android app.

The first block uses an AsyncFacebookRunner to make a request for a user's interests, if any.

If interests were found, a member variable for that user is populated with their interests from the Facebook JSON response.

The second code block checks if the user actually has interests by looking at that member variable. If there are interests, several additional lines of code are executed.

sync开发者_开发问答hronized(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();
    }
}

I want the second block to wait until friend.requestInterests() is complete before executing.

EDIT: I ended up restructuring my code to utilize the runner's onComplete method. This all came about when I modified the structure of my program and had to change up everything. Thanks all for the help.


I want the second block to wait until friend.requestInterests() is complete before executing.

The JVM ensures that the two blocks don't execute at the same time for the same instance of this.

If you additionally want to ensure that the second block only gets to run after the first has run, then you can do this using a state variable and wait / notify calls. But a better way is to use one of the synchronization classes such CountDownLatch; e.g.

private CountDownLatch latch = new CountDownLatch(1);

...

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

....

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

Indeed, if these are the only places where the relevant object state is accessed and updated, you should be able to dispense with the synchronized blocks. The calls to countdown and await will provide the necessary "comes before" relationship to ensure proper synchronization.


However, @pst's comment raises the point that there may be a better way to do this using the APIs of the Facebook library framework that your code uses.

0

精彩评论

暂无评论...
验证码 换一张
取 消