|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
Phasers (were: TaskBarriers)The flexible barrier functionality that was previously restricted to ForkJoinTasks (in class forkjoin.TaskBarrier) is being redone as class Phaser (targeted for j.u.c, not j.u.c.forkjoin), that can be applied in all kinds of tasks. For a snapshot of API, see http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/Phaser.html Comments and suggestions are very welcome as always. The API is likely to change a bit as we scope out further uses, and also, hopefully, stumble upon some better method names. Among its capabilities is allowing the number of parties in a barrier to vary dynamically, which CyclicBarrier doesn't and can't support, but people regularly ask for. The nice new class name is due to Vivek Sarkar. For a preview of some likely follow-ons (mainly, new kinds of FJ tasks that can register in various modes for Phasers, partially in support of analogous X10 functionality), see the paper by Vivek and others: http://www.cs.rice.edu/~vsarkar/PDF/SPSS08-phasers.pdf -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
|
|
|
Re: Phasers (were: TaskBarriers)Alex Miller wrote:
> This is great to see! I could definitely have used a Phaser now and again. I > blogged this note btw: > > http://tech.puredanger.com/2008/07/08/java7-phasers/ > Great; we'd welcome any nice punchy cut-n-paste-n-hack-able examples you might have for the sample usage section. > One thing I mentioned there is that the necessity of subclassing a Phaser to implement a barrier action smells to me. Why not use an external Runnable/Task action ala CyclicBarrier instead? > Because onAdvance returns termination indicator, we'd want a callback with three arguments (phaser, phase, parties) so callee knows which phaser and what its state is (which is a momentary state that will change upon return from onAdvance). It seems a little easier all around to instead have people do this by subclassing. Not too different in intent than subclassing ThreadLocal for sake of initialValue. But alternative suggestions would be welcome. -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)This is very cool. I have been rolling my own version of with similar
functionality that is nowhere near as nice or flexible. Just a quick naming question, as awesome as the name Phaser is, wouldn't PhasedBarrier possibly be more accurate? Doug Lea wrote: > The flexible barrier functionality that was previously restricted > to ForkJoinTasks (in class forkjoin.TaskBarrier) is being > redone as class Phaser (targeted for j.u.c, not j.u.c.forkjoin), that > can be applied in all kinds of tasks... cheers, jed. _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)Jed Wesley-Smith wrote:
> This is very cool. I have been rolling my own version of with similar > functionality that is nowhere near as nice or flexible. > > Just a quick naming question, as awesome as the name Phaser is, wouldn't > PhasedBarrier possibly be more accurate? > I let this sit a few days in case anyone else complained about name, but I think the consensus might be that the awesomeness of "Phaser" outweighs having the name carry the fact that it is a kind of barrier. (As Josh Bloch has said a few times, one minor failure of java.util.concurrent is that some of the class names look too imposing. For the main example, some people still use java.util.Timer just because java.util.concurrent.ScheduledThreadPoolExecutor seems so much more complicated.) I still don't love some of the method names though. Right now, names like "arriveAndAwaitAdvance()" are unambiguously descriptive. Because there are more methods you can use/call than in other kinds of barriers, we want them to be less confusing. But they get a bit clunky and verbose when you use them all the time. Suggestions welcome. A minor update of javadoc is at: http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/Phaser.html -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)I would support PhasedBarrier.
It's descriptive, consistent, short enough, and is related to the given name of its ancestor (Phaser). For an even more awesome descriptive name, I suggest: BarrierOMatic (For those too young to appreciate this, check out SNL, episode 17. Comes with 10 rotary attachments. My that's some tasty Barrier!) --Joe On Wed, Jul 16, 2008 at 4:49 AM, Doug Lea wrote:
_______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)I'm in support of just Phaser.
The method names are quite clear except it took me a bit to figure out how to do, in CyclicBarrier terms, a barrier action. When using CyclicBarrier I can pass a Runnable into the constructor. Using a Phaser I need to subclass and override the onAdvance method. I pondered this a bit when I tried to replace a CyclicBarrier with this class. Hence, I'd suggest a bit more in the class Javadoc bullet: Barrier actions, performed by the task triggering a phase advance while others may be waiting, are arranged by overriding method onAdvance, that also controls termination. (Overriding onAdvance is similar to providing a barrier action to a CyclicBarrier.) Or some such -- to better highlight the tie to this capability. Regards, Tim On Wed, Jul 16, 2008 at 7:49 AM, Doug Lea <dl@...> wrote:
_______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)I must admit I don't have a strong opinion on the Phaser/PhasedBarrier
- but mostly as I now understand what it is. The javadoc updates do improve the situation somewhat though for newcomers. On the method naming, for a CyclicBarrier you await() to arrive and the advance but for a Phaser you arriveAndAwaitAdvance(). Now while they are conceptually analagous they do have quite different semantics (different exception signature for one). While I understand the separation of arrival and waiting for advance properties, I don't understand the need to change the semantics of the call or how breaking is supported (at least in the way CyclicBarrier supports it). It would be easier to grok if the CyclicBarrier interface was supported - ie. rename arriveAndAwaitAdvance() to await() or add await() that supports interruption. My initial thought was that you could do away with _advance_ in most of the method names but the difference in the interruption policy makes that problematic. I guess it'd be interesting to know why awaitAdvance()/arriveAndAwaitAdvance() doesn't throw InterruptedException/BrokenBarrierException. Also, I don't understand how an arriveAndAwaitAdvance() can throw an IllegalStateException if the number of waiting parties becomes negative. Shouldn't it advance and return once the waiting parties reaches zero? Anyway, I am looking forward to using it in anger. cheers, jed. On 16/07/2008, at 9:49 PM, Doug Lea wrote: > Jed Wesley-Smith wrote: >> This is very cool. I have been rolling my own version of with >> similar functionality that is nowhere near as nice or flexible. >> Just a quick naming question, as awesome as the name Phaser is, >> wouldn't PhasedBarrier possibly be more accurate? > > I let this sit a few days in case anyone else complained about > name, but I think the consensus might be that the awesomeness > of "Phaser" outweighs having the name carry the fact that it > is a kind of barrier. (As Josh Bloch has said a few times, > one minor failure of java.util.concurrent is that some of > the class names look too imposing. For the main > example, some people still use java.util.Timer just because > java.util.concurrent.ScheduledThreadPoolExecutor seems > so much more complicated.) > > I still don't love some of the method names though. Right > now, names like "arriveAndAwaitAdvance()" are unambiguously > descriptive. Because there are more methods > you can use/call than in other kinds of barriers, we > want them to be less confusing. But they get a bit clunky and > verbose when you use them all the time. Suggestions welcome. > > A minor update of javadoc is at: > http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/ > Phaser.html > > -Doug > > _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)Jed Wesley-Smith wrote:
> I guess it'd be interesting > to know why awaitAdvance()/arriveAndAwaitAdvance() doesn't throw > InterruptedException/BrokenBarrierException. This is mainly experience driven. Causing BrokenBarrierExceptions when a party hits interrupt or timeout, but not if it encounters some other exception while executing usually forces people to set up two kinds of recovery -- one dealing with the barrier and the other for all other exceptions. Normally, across these, all you want to do is cause all other parties to wake up and take some evasive action. This is one use of the forceTermination method. Note that we do support awaitAdvanceInterruptibly, so you can still abort the wait on interrupt, but unlike CyclicBarrier, this doesn't itself change barrier state. Among other alternatives, you might do something like: try { p.awaitAdvanceInterruptibly(lastPhase); catch (InterruptedException ex) { record(ex); p.forceTermination(); } And/Or other actions like arriveAndDeregister or even reset. > > Also, I don't understand how an arriveAndAwaitAdvance() can throw an > IllegalStateException if the number of waiting parties becomes negative. > Shouldn't it advance and return once the waiting parties reaches zero? > It can happen if you forget to register. As in: Phaser p = new Phaser(0); p.arrive() I just realized though that this exception should be suppressed if isTerminated, since throwing it in this case just makes users life more difficult without adding any safety. Thanks for the questions! I added a few clarifications to javadoc. Also including Tim Halloran's suggestions, plus an example. (Thanks Tim!) http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/Phaser.html -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)So ... Phaser seems to be to barriers what AQS is to synchronizers. It's
powerful and flexible but adds an additional burden on the user to get the semantics right. I wouldn't push this as a replacment for CyclicBarrier or CountdownLatch as they have simpler semantics - particularly with respect to error conditions like broken barriers. In the sense that Phaser is at the same conceptual level as AQS then I find the method names appropriate. In the example usage: void runTasks(List<Runnable> list) { final Phaser phaser = new Phaser(1); // "1" to register self for (Runnable r : list) { phaser.register(); new Thread() { public void run() { r.run(); phaser.arrive(); } }.start(); } int p = phaser.arriveAndDeregister(); // deregister self otherActions(); // do other things while tasks execute phaser.awaitAdvance(p); // wait for all tasks to arrive } I don't see how the self-registration serves any purpose. Was this example trimmed down from one in which the tasks originally waited for a "start" signal? I don't understand the operation of the arriveAndDeregister method. Conceptually the phaser has two pieces of states: - number of registered parties: registered - number of parties arrived: arrivals and the phaser advances when these two become equal. So "arrive" would increment "arrivals"; and "deregister" would decrement "registered"; which implies that arriveAndDeregister() would do both! - which has to be wrong, unless de-registration only affects future phases ??? And even then I wonder why you wouldn't simply deregister() ? Cheers, David > -----Original Message----- > From: concurrency-interest-bounces@... > [mailto:concurrency-interest-bounces@...]On Behalf Of Doug Lea > Sent: Tuesday, 8 July 2008 3:19 AM > To: concurrency-interest@... > Subject: [concurrency-interest] Phasers (were: TaskBarriers) > > > > The flexible barrier functionality that was previously restricted > to ForkJoinTasks (in class forkjoin.TaskBarrier) is being > redone as class Phaser (targeted for j.u.c, not j.u.c.forkjoin), that > can be applied in all kinds of tasks. For a snapshot of API, see > http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/Phaser.html > Comments and suggestions are very welcome as always. The API is > likely to change a bit as we scope out further uses, and also, > hopefully, stumble upon some better method names. > > Among its capabilities is allowing the number of parties in a barrier > to vary dynamically, which CyclicBarrier doesn't and can't support, > but people regularly ask for. > > The nice new class name is due to Vivek Sarkar. For a preview of some > likely follow-ons (mainly, new kinds of FJ tasks that can > register in various modes for Phasers, partially in support > of analogous X10 functionality), see the paper by Vivek and others: > http://www.cs.rice.edu/~vsarkar/PDF/SPSS08-phasers.pdf > > -Doug > > > _______________________________________________ > Concurrency-interest mailing list > Concurrency-interest@... > http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)David Holmes wrote:
> > In the example usage: > ... > > I don't see how the self-registration serves any purpose. Was this example > trimmed down from one in which the tasks originally waited for a "start" > signal? Yes; thanks! Fixed to be more informative. > > I don't understand the operation of the arriveAndDeregister method. > Conceptually the phaser has two pieces of states: > - number of registered parties: registered > - number of parties arrived: arrivals > and the phaser advances when these two become equal. So "arrive" would > increment "arrivals"; and "deregister" would decrement "registered"; which > implies that arriveAndDeregister() would do both! - which has to be wrong, > unless de-registration only affects future phases ??? And even then I wonder > why you wouldn't simply deregister() ? > It is because of the intersection of two rules You can arrive only if registered You can deregister only if registered. So you can only deregister upon arrival, as a single atomic action. (Hence the name :-) Deregistration does indeed only impact future phases. If you don't care about future phases, you might as well just arrive(). I'll try to clarify this in javadocs. -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)Doug writes:
> David Holmes wrote: > > I don't understand the operation of the arriveAndDeregister method. > > Conceptually the phaser has two pieces of states: > > - number of registered parties: registered > > - number of parties arrived: arrivals > > and the phaser advances when these two become equal. So "arrive" would > > increment "arrivals"; and "deregister" would decrement "registered"; which > > implies that arriveAndDeregister() would do both! - which has to be wrong, > > unless de-registration only affects future phases ??? And even then I wonder > > why you wouldn't simply deregister() ? > > > > It is because of the intersection of two rules > You can arrive only if registered > You can deregister only if registered. > So you can only deregister upon arrival, as a single atomic action. > (Hence the name :-) > > Deregistration does indeed only impact future phases. If you don't > care about future phases, you might as well just arrive(). I just realized that there is no deregister() method, so arriveAndDeregister would be the normal usage for deregistration. That said, shouldn't there then also be arriveAndAwaitAdvanceAndDeregister ? I can see that being used for a start-latch that transforms into a stop-latch: phaser.register(); for (Runnable r : list) { phaser.register(); new Thread() { public void run() { phaser.arriveAndAwaitAdvance(); // wait for start signal r.run(); phaser.arrive(); // signal completion } }.start(); } phaser.arriveAndAwaitAdvanceAndDeregister(); // wait for everyone to be ready then start them // do other stuff phase.awaitAdvance(); // wait for everyone to complete BTW should all the methods that return the current phase number say: "@returns the current barrier phase number XXXXX, or a negative value if terminated" It seems to me we should either always says this or never - leaving the general docs to explain that a negative phase number means that the phaser has terminated. ("termination" strikes me as the wrong word here ... but I can't think of anything better right now). Cheers, David _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)David Holmes wrote:
> I just realized that there is no deregister() method, so arriveAndDeregister > would be the normal usage for deregistration. That said, shouldn't there > then also be arriveAndAwaitAdvanceAndDeregister ? I can see that being used > for a start-latch that transforms into a stop-latch: > You can get this sort of effect via int p = phaser.arriveAndDeregister(); phaser.awaitCycleAdvance(p); There is a small difference though. In the non-deregistration case, arriveAndAwaitAdvance() returns your arrival index, while awaitAdvance(arrive()) returns phase. There are use cases for both forms. We don't have an arrival index form for deregistration version though. Maybe there should be one, although I can't offhand think of a usage. An alternative I considered but at first rejected was to have arrive() and arriveAndDeregister() return a long holding both index and phase, with utilities that could decode return value for you. This would be efficient but a little icky wrt programmer usability. But maybe worth supporting these in addition to the others though, which would avoid needing arriveAndDeregisterAndAwaitAdvance(). Relatedly, maybe we should add awaitTermination(); (plus interrupt and timed versions) that is behaviorally equivalent to while (awaitAdvance(arrive()) >= 0) {} but can be a little more efficiently implemented internally. This might be handy in variations of your example. Note that it would require that you be registered in order to call it, which might be a source of errors that would only sometimes be trapped, other times only leading to unexpected behavior. -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)Doug Lea a écrit :
> David Holmes wrote: >> I just realized that there is no deregister() method, so >> arriveAndDeregister >> would be the normal usage for deregistration. That said, shouldn't there >> then also be arriveAndAwaitAdvanceAndDeregister ? I can see that >> being used >> for a start-latch that transforms into a stop-latch: >> > > You can get this sort of effect via > int p = phaser.arriveAndDeregister(); > phaser.awaitCycleAdvance(p); > > There is a small difference though. In the > non-deregistration case, arriveAndAwaitAdvance() > returns your arrival index, while > awaitAdvance(arrive()) returns phase. > There are use cases for both forms. > We don't have an arrival index form for deregistration > version though. Maybe there should be one, although > I can't offhand think of a usage. > > An alternative I considered but at first rejected > was to have arrive() and arriveAndDeregister() return > a long holding both index and phase, with utilities > that could decode return value for you. This would be efficient > but a little icky wrt programmer usability. But maybe worth > supporting these in addition to the others though, which > would avoid needing arriveAndDeregisterAndAwaitAdvance(). arrive() -> arrive(false) arriveAndDeregister() -> arrive(true) and to the similar trick to arriveAndAdvance. arriveAndAdvance() -> arriveAndAdvance(false) arriveAndDeregisterAndAwaitAdvance() -> arriveAndAdvance(true) my two cents, Rémi > ... > > -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)I like Remi's idea. Seems an easy way to get the "expected" symmetry.
David > -----Original Message----- > From: concurrency-interest-bounces@... > [mailto:concurrency-interest-bounces@...]On Behalf Of Rémi > Forax > Sent: Tuesday, 22 July 2008 10:30 PM > To: Doug Lea > Cc: concurrency-interest@...; dholmes@... > Subject: Re: [concurrency-interest] Phasers (were: TaskBarriers) > > > Doug Lea a écrit : > > David Holmes wrote: > >> I just realized that there is no deregister() method, so > >> arriveAndDeregister > >> would be the normal usage for deregistration. That said, > shouldn't there > >> then also be arriveAndAwaitAdvanceAndDeregister ? I can see that > >> being used > >> for a start-latch that transforms into a stop-latch: > >> > > > > You can get this sort of effect via > > int p = phaser.arriveAndDeregister(); > > phaser.awaitCycleAdvance(p); > > > > There is a small difference though. In the > > non-deregistration case, arriveAndAwaitAdvance() > > returns your arrival index, while > > awaitAdvance(arrive()) returns phase. > > There are use cases for both forms. > > We don't have an arrival index form for deregistration > > version though. Maybe there should be one, although > > I can't offhand think of a usage. > > > > An alternative I considered but at first rejected > > was to have arrive() and arriveAndDeregister() return > > a long holding both index and phase, with utilities > > that could decode return value for you. This would be efficient > > but a little icky wrt programmer usability. But maybe worth > > supporting these in addition to the others though, which > > would avoid needing arriveAndDeregisterAndAwaitAdvance(). > In my opinion, we could use a boolean deregister as parameter of arrive. > arrive() -> arrive(false) > arriveAndDeregister() -> arrive(true) > > and to the similar trick to arriveAndAdvance. > arriveAndAdvance() -> arriveAndAdvance(false) > arriveAndDeregisterAndAwaitAdvance() -> arriveAndAdvance(true) > > my two cents, > Rémi > > ... > > > > -Doug > > _______________________________________________ > Concurrency-interest mailing list > Concurrency-interest@... > http://cs.oswego.edu/mailman/listinfo/concurrency-interest > _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers)David Holmes wrote:
> I like Remi's idea. Seems an easy way to get the "expected" symmetry. > Not so sure. Seems a bit error seeking. Looking at or writing: phaser.arrive(true). doesn't plainly indicate whether you mean to deregister or stay registered (or become registered?) And using an enum instead seems ugly enough to annoy people. phaser.arrive(Phaser.STAY_REGISTERED); Probably better would be to add a few more methods to fill out the possibilities. Even though their names would be uglier, they cover cases people will rarely if ever use anyway. -Doug _______________________________________________ Concurrency-interest mailing list Concurrency-interest@... http://cs.oswego.edu/mailman/listinfo/concurrency-interest |
|
|
Re: Phasers (were: TaskBarriers) |