Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > ThreadPoolExecutor backport

Reply
Thread Tools

ThreadPoolExecutor backport

 
 
Philipp
Guest
Posts: n/a
 
      07-31-2008
Hello
I'm using the backport to java 1.4 of Doug Lea's java.util.concurrent
package. In the doc for ThreadPoolExecutor, there is a snipped of code
to build a pausable thread pool executor. The snipped is below.
Q: Why does the boolean flag isPaused need not be volatile?
As I see it, it will be polled and set by different threads and
nothing guarantees a memory barrier.
Q2: Does it make a difference if you are in the 1.4 or java 5 memory
model?
Thanks for your comments. Phil

--- Code from JavaDoc ---

class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();

public PausableThreadPoolExecutor(...) { super(...);

protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}

public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}

public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}}
 
Reply With Quote
 
 
 
 
Philipp
Guest
Posts: n/a
 
      07-31-2008


Lew a écrit :
> Philipp wrote:



class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();

public PausableThreadPoolExecutor(...) { super(...);

protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}

public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}

public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}}

> > Q: Why does the boolean flag isPaused need not be volatile?
> > As I see it, it will be polled and set by different threads and
> > nothing guarantees a memory barrier.

>
> Nothing but the 'pauseLock.lock()', that is.


Thanks for your non-answer. It made me look harder.
Actually, the thing that happens is that in beforeExecute(),
unpaused.await() unlocks the acquired lock pauseLock. This then
(later) gets locked by resume() where signalAll awakes the waiting
thread in beforeExecute(). At this time, the waiting thread is awake,
but cannot execute because it must first reacquire the lock (which is
still held in resume() ). As soon as resume() releases the lock, it is
reacquired by beforeExecute(). Now what makes it all work without the
volatile keyword, is that the unlock() in resume() establishes a
happens-before relation with respect to a subsequent lock of
pauseLock. So the value of isPaused is updated as soon as the waiting
thread starts to run again.

Phil
 
Reply With Quote
 
 
 
 
Lew
Guest
Posts: n/a
 
      07-31-2008
Philipp wrote:
> > > Q: Why does the boolean flag isPaused need not be volatile?
> > > As I see it, it will be polled and set by different threads and
> > > nothing guarantees a memory barrier.

>
> > Nothing but the 'pauseLock.lock()', that is.

>
> Thanks for your non-answer. It made me look harder.


"non-answer"? It turned to to be exactly the answer, as your
description clearly shows.

Happy to help.

--
Lew


 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      07-31-2008
On 31.07.2008 15:19, Lew wrote:
> Philipp wrote:


Btw, AFAIK the implementation you are using preceded Java 5 so it is not
a backport.

>> Q2: Does it make a difference if you are in the 1.4 or java [sic] 5
>> memory model?

>
> Yes, but not to this snippet.


Are you sure with regard to "volatile"? I faintly remember articles
about the flaws of the Java memory model before Java 5 and I believe
volatile handling was one of them. Or am I mixing up something?

Kind regards

robert
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      07-31-2008
On Jul 31, 2:49*pm, Robert Klemme <(E-Mail Removed)> wrote:
> On 31.07.2008 15:19, Lew wrote:
>
> > Philipp wrote:

>
> Btw, AFAIK the implementation you are using preceded Java 5 so it is not
> a backport.
>
> >> Q2: Does it make a difference if you are in the 1.4 or java [sic] 5
> >> memory model?

>
> > Yes, but not to this snippet.

>
> Are you sure with regard to "volatile"? *I faintly remember articles
> about the flaws of the Java memory model before Java 5 and I believe
> volatile handling was one of them. *Or am I mixing up something?


You are correct, but 'volatile' was not used in the snippet, so that
difference is, as stated, not relevant to the snippet.

--
Lew
 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      07-31-2008
On 31.07.2008 20:52, Lew wrote:
> On Jul 31, 2:49 pm, Robert Klemme <(E-Mail Removed)> wrote:
>> On 31.07.2008 15:19, Lew wrote:
>>
>>> Philipp wrote:

>> Btw, AFAIK the implementation you are using preceded Java 5 so it is not
>> a backport.
>>
>>>> Q2: Does it make a difference if you are in the 1.4 or java [sic] 5
>>>> memory model?
>>> Yes, but not to this snippet.

>> Are you sure with regard to "volatile"? I faintly remember articles
>> about the flaws of the Java memory model before Java 5 and I believe
>> volatile handling was one of them. Or am I mixing up something?

>
> You are correct, but 'volatile' was not used in the snippet, so that
> difference is, as stated, not relevant to the snippet.


Actually I canceled my posting because I discovered my reading error the
second after hitting "send" - but apparently Usenet was too fast for me.

Thanks for clarifying anyway! Always good to get some of your well
thought out advice / comments.

Kind regards

robert
 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      07-31-2008
Robert Klemme wrote:
> >> I faintly remember articles
> >> about the flaws of the Java memory model before Java 5 and I believe
> >> volatile handling was one of them. *Or am I mixing up something?


What you are remembering is that 'volatile' prior to Java 5 only
guaranteed visibility of changes through the volatile variable
itself. Other changes might not have propagated.

So given

class Foo
{
volatile int flag;
int value; // not volatile
...
}

the old memory model would guarantee visbility of changes to 'flag',
but not other changes. Code like:

value += 17;
flag = 1;

in one thread guaranteed that another thread would see 'flag' as 1,
but not that it would see the change in 'value'. In the new memory
model, the change to 'value' /happens-before/ the change to 'flag', so
it is visible across threads.

--
Lew
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
2.5/2.4 multiprocessing backport doc typo Daniel Fetchinson Python 1 03-30-2009 12:14 AM
backport of 'set' to python 2.3? Daniel Fetchinson Python 1 05-22-2008 02:02 AM
Backport from ruby 1.9, including constants Victor \Zverok\ Shepelev Ruby 3 02-12-2007 03:59 AM
1.9 Backport? Trans Ruby 8 10-27-2006 03:27 PM
ThreadPoolExecutor implementation question allen@rrsg.ee.uct.ac.za Java 0 10-04-2005 03:14 PM



Advertisments