When reading DownloadService class in Android Open Source Project, I noticed a use of @GuardedBy annotation, which is kind of like synchronized keyword in Java but with alternative locks. We may use this annotation as:
1 2 3 4 | public class foo { @GuardedBy ( "this" ) public String str; } |
As we can see, the usage is @GuardedBy(lock) which means the guarded fields or methods can be accessed by some thread only when the thread is holding the lock. We can specify the lock to the following types:
- this : The intrinsic lock of the object in whose class the field is defined.
- class-name.this : For inner classes, it may be necessary to disambiguate ‘this’; the class-name.this designation allows you to specify which ‘this’ reference is intended
- itself : For reference fields only; the object to which the field refers.
- field-name : The lock object is referenced by the (instance or static) field specified by field-name.
- class-name.field-name : The lock object is reference by the static field specified by class-name.field-name.
- method-name() : The lock object is returned by calling the named nil-ary method.
- class-name.class : The Class object for the specified class should be used as the lock object.
An example:
1 2 3 4 5 6 | public class BankAccount { private Object credential = new Object(); @GuardedBy ( "credential" ) private int amount; } |
In the code snippet above, amount can be accessed when someone has got the synchronization lock of credential, so amount in a BankAccount is guarded by the credential. Let’s add something to this class.
1 2 3 4 5 6 7 8 9 | public class BankAccount { private Object credential = new Object(); @GuardedBy ( "credential" ) private int amount; @GuardedBy ( "listOfTransactions" ) private List<Transaction> listOfTransactions; } |
We now have a list of Transactions in the BankAccount. The List object has many elements so that it has references to all the elements in the list. Here we use @GuardedBy(“listOfTransactions”) to specify that the lock is associated with the objects which listOfTransactions refers to. In other words, someone must hold locks of all the Transactions in order to hold the lock of this List object.