Christopher Dolan wrote:
Attached is a minimalist initial patch. I'm not happy that I had to
store a reference to the thread in the Runnable... But otherwise I
wasn't sure how to interrupt it from removeTask() without a separate map
of TaskThread to Thread. There's all a null pointer race in this patch
if you try to remove a task before it's run() method executes.
I am concerned about the null pointer race, and think it may last a
little bit longer on some multiprocessor systems than is immediately
obvious.
The first thing in the life of the new thread that I can see
establishing a "happens-before" relationship
[http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4.5]
from the write to reads of myThread is the end of the first execution of
the synchronized block in the run method. In a multiprocessor with
release consistency, the write might not be visible to another thread
that wins the race for the TaskManager synchronization, even if it has
already happened on a processor running the new thread.
The race could be removed by having a method:
private void setThread(Thread t){
myThread = t;
}
in the Runnable, and having the thread creation code call it immediately
before starting the thread. At that point, the thread creation code has
references to both the Thread and the Runnable, and is synchronized on
the TaskManager object.
Apologies for not writing, testing, and presenting a modified version of
the patch - I am having problems running qa on my WindowsXP system.
Patricia