Comments in line...

> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]]
> On Behalf
> Of [EMAIL PROTECTED]
> Sent: Sunday, April 22, 2001 1:59 PM
> To: Paul Kinnucan
> Cc: JDE List
> Subject: Re: more on testing JDEbug
>
>
>
> In message <[EMAIL PROTECTED]>,
> Paul Kinnucan write
> s:
>
> : Eric, I am a little confused. Are you saying that my thread
> priority "fix"
> : in beta10 is an improvement? If so, that is very
> interesting. I believer
> : there other debugger threads that JDEbug sets to max
> priority (actually
> : MAX_PRIORITY-1). I've never understood why the code, which
> was written by a
> : Sun summer intern, was setting the priority of these
> threads. However,

If those threads spend most of their life blocked, they may need the higher
priority to get scheduled for running when they become runnable.


> : since the intern was working as a member of the JPDA team,
> I assumed he had
> : access to inside information so I was reluctant to touch
> his code in this
> : area. Recently, however, I have been reading Holub's
> "Taming Java Threads"
> : and found his discussion of how thread scheduling differs
> drastically from
> : platform to platform enlightening and horrifying. Holub's advice is

Yes, the big difference is if the platform is using the JVM's "green thread"
model or natively handles the threading for the JVM (native threads).  Not
only do green and native threads differ, but the native threads per platform
differ!


> : basically just not to monkey with thread prioirty since you
> can't set
> : priorities in a platform-independent way. So I'm inclined
> to comment out
> : all the set-priority calls in the JDEbug code.

It is best to leave thread priorities alone, except for a few rare
situations like these for example:
- a thread that continually runs without blocking and would probably cause
CPU starvation to other threads should have its priority lowered as the all
around best solution (adding sleeps/yields causes it to selectively block
and has its uses as well, but is not as overall effective as the priority
adjustment).
- a thread that usually lives its life blocked and when it is unblocked
needs to immediately run should have its priority raised to have the best
chance at being scheduled.

In Java, basically the thread with the highest priority (and the "next in
queue" for the priority level - whatever queuing mechanism the platform has
if at all) runs until it blocks or a higher-priority thread is runnable.
Sometimes a little change is necessary for responsiveness or (lock or CPU)
starvation prevention.


FYI - Scott Oaks' "Java Threads" and Doug Lea's "Concurrent Java
Programming" are also excellent resources.  The first is a
learning/reference book, the second is patterns for concurrency.


> Yes, the beta10 fix yielded a working debugger in both emacsen.  There
> were no changes to code or to the number of ambient processes between
> the upgrade, and I repeated the exercise with a downgrade
> (didn't work)
> and a re-upgrade (worked).  But also keep in mind the importance of
> upgrading the VM itself from 1.3 => 1.3.1.

The thread change may be a red herring - the JDK upgrade may have fixed a
bug.  Best to do each individually...


> In my experience Holub is exactly right.  In VMs (linux) that
> implement
> threading as processes, the scheduler in the kernel has an opportunity
> (indeed, an obligation) to control "threads" in a way that
> just doesn't
> happen when threading is implemented within a single process.
>
> I was curious, so I wrote a little priority test in which I start two
> threads, one with MAX_PRIORITY and the other with MIN_PRIORITY.
> Each thread has an instance of a Runnable whose run method looks like
> this:
>
> long runcount = 0L;
>
> public void run() {
>   try {
>     while (true) {
>       System.out.println(Thread.currentThread().toString() + ":" +
>                          runcount++);
>     } // end of while (true)
>   } catch (Exception e) {
>     e.printStackTrace();
>   } // end of try-catch
> }
>
> Since these runnables are just competing for CPU time (and
> System.out, of
> course), you'd expect the one that belongs to the Thread with
> MAX_PRIORITY
> to eventually end up with a much higher runcount.

Not necessarily...don't forget the blocked state of the thread without the
lock.


> Curiously, my results are exactly the opposite: if left to run ~10,000
> times, the MIN_PRIORITY thread ends up about 1,000 iterations ahead.
> I ran the test a few times, for different durations, and MIN_PRIORITY
> always got more cycles.

Which thread are you starting first?

Hmmm.  I need to think about this and test myself too.  Off the top of my
head, I think it may be an unfair test because they are synchronizing on the
out object.  Each iteration spends nearly its whole time in the out sync.
So after the lock is released, all waiting threads are notified and then
compete for the lock again.  They are in a tight loop, and my guess is the
lower priority thread gets the lock again before the blocked higher priority
thread has a chance (it doesn't make sense yet, but perhaps it doesn't get
into the runnable state before it is blocked again).  The JVM is probably
trying to get the higher priority thread to run, but because it is usually
blocked waiting for the out lock, it can't.

Perhaps try a different test which does not have a sync in the
loop...instead loop for 10,000 times and print the sum result only at the
end.  I hope I can get to this this weekend.


> I conclude from this (completely unscientific) test that you and Holub
> are exactly right - setting thread priorities isn't worth the trouble,
> because of the inherent OS dependencies in scheduling.
>
> As to trusting the inside information of Sun's summer intern
> - well....
> The JDK has quite a few classes that were probably written by well
> meaning, but poorly mentored summer interns.  The Observable/Observer
> classes are a disaster because of the requirement that you sublass
> Observable to use them (observable should've been an interface and Sun
> should've provided an "observable support" class to which implementors
> could delegate, a la property change support).
> java.text.BreakIterator
> is terrible because it cannot be extended to introduce more
> intelligent
> segmentation rules, which is why IBM had to rewrite it.  Making Stack
> a subclass of Vector is pretty awful too, since you end up with a data
> structure that can be altered in all kinds of un-stack-like ways if
> people aren't paying attention.
>
> At any rate, it's very easy to criticize someone else with the benefit
> of 20/20 hindsight (and it's fun too, as Homer Simpson once
> said, ha ha),
> but suffice it to say that I'm not exactly shocked that a
> javasoft insider
> would flub some multithreading code - it's still darn hard to
> get right,
> even if you're spending a summer in the Silly Valley.
>
> Eric
>
>

Reply via email to