并且给出了结果:
Thread 0
Thread 1
Thread 2
Thread 0
Thread 1
Thread 2
Thread 0
Thread 1
Thread 2
也就是Thread 0 Thread 1 Thread 2 按照这个顺序交替出现,作者指出虽然结果和我们预料的似乎相同,但是这个结果是不可靠的。果然被我的双核电脑验证了:
Thread 0
Thread 1
Thread 2
Thread 2
Thread 0
Thread 1
Thread 1
Thread 0
Thread 2
看来线程真的很不可靠啊。但是尽管如此,sleep()方法仍然是保证所有线程都有运行机会的最好方法。至少它保证了一个线程进入运行之后不会一直到运行完位置。
时间的精确性。再强调一下,线程醒来之后不会进入运行状态,而是进入就绪状态。因此sleep()中指定的时间不是线程不运行的精确时间!不能依赖sleep()方法提供十分精确的定时。我们可以看到很多应用程序用sleep()作为定时器,而且没什么不好的,确实如此,但是我们一定要知道sleep()不能保证线程醒来就能马上进入运行状态,是不精确的。
sleep()方法是一个静态的方法,它所指的是当前正在执行的线程休眠一个毫秒数。看到某些书上的Thread.currentThread().sleep(1000); ,其实是不必要的。Thread.sleep(1000);就可以了。类似于getName()方法不是静态方法,它必须针对具体某个线程对象,这时用取得当前线程的方法Thread.currentThread().getName();
B、线程优先级和让步。
线程的优先级。在大多数jvm实现中调度程序使用基于线程优先级的抢先调度机制。如果一个线程进入可运行状态,并且它比池中的任何其他线程和当前运行的进程的具有更高的优先级,则优先级较低的线程进入可运行状态,最高优先级的线程被选择去执行。
于是就有了这样的结论:当前运行线程的优先级通常不会比池中任何线程的优先级低。但是并不是所有的jvm的调度都这样,因此一定不能依赖于线程优先级来保证程序的正确操作,这仍然是没有保障的,要把线程优先级用作一种提高程序效率的方法,并且这种方法也不能依赖优先级的操作。
另外一个没有保障的操作是:当前运行的线程与池中的线程,或者池中的线程具有相同的优先级时,JVM的调度实现会选择它喜欢的线程。也许是选择一个去运行,直至其完成;或者用分配时间片的方式,为每个线程提供均等的机会。
优先级用正整数设置,通常为1-10,JVM从不会改变一个线程的优先级。默认情况下,优先级是5。Thread类具有三个定义线程优先级范围的静态最终常量:Thread.MIN_PRIORITY (为1) Thread.NORM_PRIORITY (为5) Thread.MAX_PRIORITY (为10)
静态Thread.yield()方法。
它的作用是让当前运行的线程回到可运行状态,以便让具有同等优先级的其他线程运行。用yield()方法的目的是让同等优先级的线程能适当地轮转。但是,并不能保证达到此效果!因为,即使当前变成可运行状态,可是还有可能再次被JVM选中!也就是连任。
非静态join()方法。
让一个线程加入到另一个线程的尾部。让B线程加入A线程,意味着在A线程运行完成之前,B线程不会进入可运行状态。
Thread t = new Thread();
t.start();
t.join;
这段代码的意思是取得当前的线程,把它加入到t线程的尾部,等t线程运行完毕之后,原线程继续运行。书中的例子在我的电脑里效果很糟糕,看不出什么效果来。也许是CPU太快了,而且是双核的;也许是JDK1.6的原因?
12、没总结完。线程这部分很重要,内容也很多,看太快容易消化不良,偶要慢慢地消化掉……
附: java原著中对线程的解释。
e文原文:
Thread Scheduling
In Java technology,threads are usually preemptive,but not necessarily Time-sliced(the process of giving each thread an equal amount of CPU time).It is common mistake to believe that "preemptive" is a fancy word for "does time-slicing".
For the runtime on a Solaris Operating Environment platform,Java technology does not preempt threads of the same priority.However,the runtime on Microsoft Windows platforms uses time-slicing,so it preempts threads of the same priority and even threads of higher priority.Preemption is not guaranteed;however,most JVM implementations result in behavior that appears to be strictly preemptive.Across JVM implementations,there is no absolute guarantee of preemption or time-slicing.The only guarantees lie in the coder’s use of wait and sleep.
The model of a preemptive scheduler is that many threads might be runnable,but only one thread is actually running.This thread continues to run until it ceases to be runnable or another thread of higher priority becomes runnable.In the latter case,the lower priority thread is preempted by the thread of higher priority,which gets a chance to run instead.
A thread might cease to runnable (that is,because blocked) for a variety of reasons.The thread’s code can execute a Thread.sleep() call,deliberately asking the thread to pause for a fixed period of time.The thread might have to wait to access a resource and cannot continue until that resource become available.
All thread that are runnable are kept in pools according to priority.When a blocked thread becomes runnable,it is placed back into the appropriate runnable pool.Threads from the highes