User Guide - Part Four
In my previous installment I showed you some examples of using continuations. From them you can see continuations are a sort of non-local jumps (a bit like exceptions). Isn't that dangerous? Yes, it is - but fun! Let's have an example:
@interpretable Continuation aMethod() {
return new Continuation();
}
@interpretable void anotherMethod() {
Continuation cont = aMethod();
synchronized (this) {
cont.returnTo(cont);
}
}
Note the
synchronized
block. Now that's nasty, right? If you jump somewhere else, just like that, this
will remain locked, right? Well, no... Remember continuations are “a bit like exceptions” and the JauVM will handle the unlocking for you, just like the JVM does with exceptions. We have a new problem though:@interpretable Continuation aMethod() {
return new Continuation();
}
@interpretable void anotherMethod() {
Continuation cont = null;
synchronized (this) {
cont = aMethod();
}
cont.returnTo(cont);
}
What's happening here? Well, you acquire the lock, then you save the
Continuation
and release the lock. Afterwards you invoke the Continuation
, and you're suddenly inside the synchronized
block without the lock.Now wait a minute. Can't the JauVM reacquire the lock for me? Unfortunately no, it's not that simple. And we have the same problem with
try
... finally
too - finally
s are ran, but we have no “initially
”.To amend this issue an new
Throwable
was devised - the continuing
class. It can be used to tag a catch
clause of a try
block as the code to be run when that try
is reentered. Confusing? Examples will help.In the presence of continuations code, a
synchronized
should look like this:synchronized (this) {
try {
// ...
} catch (continuing c) {
Monitor.enter(this);
}
}
And a
try
... finally
(safeguarding a JDBC connection, in this case) should be:Connection conn = pool.getConnection();
try {
// ...
} catch (continuing c) {
conn = pool.getConnection();
} finally {
conn.close();
}
As you can see, the
catch
continuing
clause is about reacquiring the resources you've freed when you first left the try
block.But what's this
continuing
class like? Here it is:public final class continuing extends Error {
private continuing() {
}
}
The class is
final
and the constructor private
because there should be no objects of this kind - again this is just a tag! It extends Error
for it mustn't be a checked exception, and shouldn't normally be caught either - though it doesn't make a difference if you catch Throwable
, only continuing
works.Also, you're probably curious about that
Monitor
class. Well, it will have to be written in assembly, and I haven't made up my mind about an assembler yet (Jamaica, Jasmin...) It'll have at least enter
and exit
static
methods, but you'll see.And that's it, for now! User guide over. Not complete, but I hope I've passed along the general picture. By the way, I'm open to suggestions for names for these all classes and methods (especially the
continuing
exception, which I particularly dislike).Thanks for “listening”!
No comments:
Post a Comment