[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Sun JSR 166 - Concurrency Utilities
Sorry - I'm afraid I have not been able to keep up with everything
recently. In particular, the JSR166, :(. Just a few comments for now.
> * There is a locks package that contains Lock/ReentrantLock (an
> exclusive read/exclusive write lock) and
> ReadWriteLock/ReentrantReadWriteLock (a concurrent read/exclusive write
> lock). The latter is quite similar to the JCSP Crew class, which Peter
> Welch described in gory detail a few years ago (in a memorable
> two-projector lecture that took an hour to describe about 40 lines of
> code - and still left some people unsure they really understood what was
> going on - such things have immensely complicated dynamics. I digress).
The 40 lines of code I spent an hour trying to convince everyone about
were those from Tony Hoare, published (I think) in his pre-CSP CACM paper
on monitors (1975). They used his wait/signal and multiple condition
variable monitor mechanisms. The logic was short but really hard to
digest. You had to understand all four monitor methods (the claim and
release for reader and writer) at the same time - understanding them
individually did not help.
The point of the talk was that I then spent about 10 minutes explaining
a CREW lock implementation based upon CSP primitives. These could be
studied a bit at a time and scaled up concurrently to give a solution
that was not just correct ... but was *obviously* correct. That's
why I like to work with CSP primitives ... their semantics are composeable.
That CSP algorithm is exactly how JCSP Crew locks are implemented.
A derived version implements the (much much faster) CREW locks in occam.
> Locks are helpful, I have found, but there is always some risk of not
> balancing the acquires and releases, with variously adverse consequences.
That's why they probably need binding at the language level - something
we have not done yet for occam (but can) or Java (and can't, except by
pre-processor and then it's not Java any more).
> * InterruptedException is widely thrown. I am not sure whether this is a
> good thing: although it would apparently be a practical necessity, it
> makes reasoning about concurrency much much more difficult because it
> introduces many more states. A reasoned design is able to abort by
> design, not by exception. This is admittedly a different mindset, and
> underpins the difference between the CSProcess and the Thread classes. I
> don't know how this might be resolved: maybe others would comment.
I don't know either - but it's something we need to address. To support
unreliable networking (and other things), we are agonising about putting
exceptions into occam ... or something with the same power. The problem
is to do this without damaging any of the existing (transformation) laws,
gaining the hoped-for benefits and preserving the nano-second process
management overheads. The JCSP Networking Edition already reports back
newtork failures in network channels by throwing (non-checked) exceptions.
> * Futures provide asynchronous method calling.
I've never felt a need for this (but don't mind if others do :). So long
as concurrency is light enough (both in its expression and runtime),
async communications are easy to handle using sync comms and par - e.g.
ASYNC foo (args) -- sets up call, returns straight away
... get on with other stuff
WAIT foo -- blocks until the above call completes
is just a less structured way of saying:
CALL foo (args) -- occam3 style synchronized CALL channel
... get on with other stuff
We need the PRI to ensure that, if competing for silicon, the CALL gets
scheduled (which will set it up) before the "other stuff". The barrier
sync at the end of the PAR block automatically gives us the WAIT.
[Note for occamists: the above CALL could be any channel communication
as well - input or output.]
Last thought for now. Tony Hoare always says that CSP primitives are
really primitive - for example, they are (logically) at a much lower
level than, say, monitors or other forms of locking. Therefore, it is
illogical to implement the latter things (in libraries, languages or
silicon) and then proceed to implement CSP mechanisms on top of them
(which is, of course, precisely what we have done with JCSP - but,
given the JVM, we had little choice!).
The logical thing is to implement CSP primitives at the lowest possible
level (preferably in silicon) and, then, use them as the basis for
building whatever higher level mechanisms you need. So, the thesis
is that CSP gives us a better (i.e. more semantically powerful and
malleable and more efficient) set of primitives. Those higher level
need have no resemblance to CSP, if that's the way some prefer.