Java Reference
In-Depth Information
34 synchronized (InterruptedExceptionExample.class) {
35 log.info(getName() + ": waiting for some resource.");
36 InterruptedExceptionExample.class.wait();
37 }
38 } catch (InterruptedException ie) {
39 // this is the bit we are interested in
40 }
41 }
42 }
43
44 public class LockAttemptFailedException extends Exception {
45 public LockAttemptFailedException(String msg, Throwable t) {
46 super(msg, t);
47 }
48 }
49 }
■
Note
When we call
join
in line 12 there is the risk that an
InterruptedException
may be thrown.
Handling this exception is not relevant to our discussion point, so we have decided to allow the
main
method to throw the exception as specified in line 6.
As noted in the comment at line 31, the
getLock
method needs something to happen
before it will complete—but for the purposes of this example we have not declared what that
will be. If this were a section of code from a real-life application it might be waiting for a lock
to be released, or it might be waiting for a resource to become free. All we care about for this
example is that, regardless of what we were waiting for, it won't ever happen.
The important point of this example code is that we are calling the
wait
method in line 36,
and the
wait
method can throw an
InterruptedException
; however, the signature for the
getLock
method states that only the
LockAttemptFailedException
(which does not extend
InterruptedException
) will be thrown. So we must do something with the
InterruptedException
that we are catching at line 38.
■
Tip
As shown in lines 34 and 36, every class can itself be used as the object to be synchronized on. You
do not even need an instance of the class—you can just use the
class
literal. In most cases, you will find
that there are specific objects you wish to synchronize on; however, if there are no apparent objects, do not
automatically assume that you are going to have to create an object just so you can use it as a mutual exclu-
sion lock (a lock that mutually excludes access to all other threads as long as one thread owns the lock; also
known as a mutex). Conversely, don't use this feature where it doesn't apply—if you want to make explicit
what a particular mutex is being used for, it might be worthwhile creating an
Object
with a suitably descrip-
tive name just to make the code clear. Making these sorts of decisions is all a part of being a developer.