classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Thread/VMThread proposal


From: David Holmes
Subject: RE: Thread/VMThread proposal
Date: Tue, 29 Jul 2003 12:43:52 +1000

> Thanks for taking the time to comment!

No problem.

> > - You may need more lifecycle management in VMThread. For
> > example, a thread that has stop() called on it before it is
started is
> > "stillborn".
>
> The docs do say that, but my tests suggest that Sun just
> ignores stop() when called on an unstarted thread.

The JDK has always been buggy with regard to stop() and once they
deprecated it no effort was made to fix things. I recommend following
the spec - let the JDK be the only buggy implementation out there.

> > - VMThread.join() should be implemented using wait/notify ...
>
> IMHO, this is too heavyweight for the default VMThread. I
> expect most VMs to supply their own version of VMThread which has a
better
> implementation of join (based on some native join-like mechanism).

Heavyweight? There's an irony there given that some VM's implement
Thread.sleep by doing a timed wait() on a private object :) (helps to
isolate the interrupt mechanics).

I think wait/notifyAll is the simplest, most obvious and correctly
portable implementation for this. Doing a polling loop is generally
poor form and a sleep of 1 may not even sleep at all if the platform
uses a clock resolution greater than that. As for "native join-like
mechanisms" they would have to use events in win32 or mutex+condVar in
POSIX as only one thread can join another in pthreads. I'd go for a
default mechanism that is simple and guaranteed correct.

> > - having VMThread.currentThread create a Thread if the current
> > VMThread is "unbound" seems inappropriate. > Thread.
>
> Unfortunately, I think this is required, because native
> threads can call into Java code.

In JNI a thread must attach itself to the JVM before it can make any
calls. This is when a Java Thread is constructed for that native
thread. Other native mechanisms may differ of course. Either way it
seems this is far too implementation specific to make it the default.

> > - in general you need more synchronization to ensure atomicity of
> > actions, and in particular to ensure a thread does not terminate
> > whilst a method is being invoked upon it. Sequences such as:
> >    VMThread t = this.vmThread;
> >    if (t != null) t.XXX();
> > can still throw NullPointerException if the thread
> terminates between
> > the null check and the invocation.
>
> No they can't. t is either null or it isn't, it doesn't change.

Duh! Sorry about that.

> Note that I do assume that the native methods do the right
> thing, in case the thread has already terminated.

Right. It's a slightly simpler model, in my view, to ensure this can't
happen, but that's your call.

> > The simplest solution to make the
> > vast majority of Thread methods synchronized
>
> I went through the code again and looked at the memory
> model issues.

You should make Thread.getPriority synchronized so that it is atomic
with respect to Thread.setPriority. That avoids the problem of seeing
a Thread.priority value that hasn't yet been transmitted to the
VMThread.

Some of your other changes look a bit "too clever" eg:

static VMThread create(Thread thread, long stacksize)
    {
        VMThread vmThread = new VMThread(thread, stacksize);
        // memory barrier, to make sure VMThread is fully inialized before it
        // is seen from another thread
        synchronized(thread) {}
        synchronized(thread) {}
        return vmThread;
    }

The synchronization belongs at the point where a shared reference is
published. In the case of Thread.start() it suffices that the return
value from create is assigned to the volatile vmThread variable. That
has all the right semantics under the currently proposed memory model
and no current VM is likely to do this wrong.

If the Thread reference being passed in was for an object created in
another thread and was obtained without synchronization, then no local
synchronization in create will force the necessary "flush" from the
creating thread. But given that all fields of Thread are either
volatile or accessed under synchronization, this should not be an
issue either.

The native starting mechanism will ensure that the new thread can see
everything at the Java level.

Similarly in VMTHread.currentThread, all will be well if
VMThread.thread is volatile. Though I'm unclear how the Thread
reference for the newly constructed Thread would be obtained by
another thread. The only mechanism would be via the Threadgroup and
there must be synchronization used in both the addThread and enumerate
methods to deal with that anyway.

The use of two synchronized blocks is redundant from a memory barrier
perspective as far as I am aware.

We can discuss this offline.

Cheers,
David Holmes





reply via email to

[Prev in Thread] Current Thread [Next in Thread]