使用了sleep方法的代码程序输出的结果任然是无序的,我修改上面的代码:
package cn.com.sxia;public class SleepingThread extends Thread{
private int countDown = 5;
private static int threadCount = 0;
public SleepingThread(){
super("" + ++threadCount);
start();
}
public String toString(){
return "#" + getName() + ": " + countDown;
}
public void run(){
while(true)
{
System.out.println(this);
if (--countDown == 0)
return;
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0;i < 5;i++)
{
new SleepingThread().join();
}
}
}
private int countDown = 5;
private static int threadCount = 0;
public SleepingThread(){
super("" + ++threadCount);
start();
}
public String toString(){
return "#" + getName() + ": " + countDown;
}
public void run(){
while(true)
{
System.out.println(this);
if (--countDown == 0)
return;
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0;i < 5;i++)
{
new SleepingThread().join();
}
}
}
结果如下:
#1: 5
#1: 4
#1: 3
#1: 2
#1: 1
#2: 5
#2: 4
#2: 3
#2: 2
#2: 1
#3: 5
#3: 4
#3: 3
#3: 2
#3: 1
#4: 5
#4: 4
#4: 3
#4: 2
#4: 1
#5: 5
#5: 4
#5: 3
#5: 2
#5: 1
#1: 4
#1: 3
#1: 2
#1: 1
#2: 5
#2: 4
#2: 3
#2: 2
#2: 1
#3: 5
#3: 4
#3: 3
#3: 2
#3: 1
#4: 5
#4: 4
#4: 3
#4: 2
#4: 1
#5: 5
#5: 4
#5: 3
#5: 2
#5: 1
以上实例表明sleep,yield方法都不是决定线程执行顺序的因素,而join可以有序的定义线程执行的顺序。
作为程序员的我很喜欢按次序的输出结果,但是让线程输出的结果变得有规律真的有这个必要吗?我们回顾下我们使用过的语言,假如编程语言里没有线程,那么一切程序应该都是按顺序进行的,有了线程的语言我们可以打破这个固有的顺序,让程序随时随地进行执行,这样就可以开发并行的计算任务了,按顺序输出的线程是完全没有使用价值的程序,而且线程机制总会消耗到一定的系统资源,编写有序的线程也是极大的资源浪费。
我曾经在一次面试时候说出了上面的理解,但是面试官马上问了一个问题难住了我,线程本来就该是无序的,那么我们就任意让线程随便执行,这个你认为合理吗?当时我从join角度解释这个问题,现在复习线程知识发现通过join阐述答案是自己思路太窄了,线程虽然注定是无序,但并不是说所有线程都可以让它肆意的暂用宝贵的CPU资源,java语言里还有方法可以控制它,线程还有一个功能:线程的优先级,大家看下面的代码:
package cn.com.sxia;public class SimplePriorities extends Thread {
private int countDown = 5;
private volatile double d = 0;
public SimplePriorities(int priority){
setPriority(priority);
start();
}
public String toString(){
return super.toString() + ": " + countDown;
}
public void run(){
while(true)
{
for (int i = 1;i < 100000;i++)
{
d = d + (Math.PI + Math.E);
System.out.println(this);
if (--countDown == 0)
return;
}
}
}
public static void main(String[] args)
{
new SimplePriorities(Thread.MAX_PRIORITY);
for (int i = 0;i < 5;i++)
{
new SimplePriorities(Thread.MIN_PRIORITY);
}
}
}
private int countDown = 5;
private volatile double d = 0;
public SimplePriorities(int priority){
setPriority(priority);
start();
}
public String toString(){
return super.toString() + ": " + countDown;
}
public void run(){
while(true)
{
for (int i = 1;i < 100000;i++)
{
d = d + (Math.PI + Math.E);
System.out.println(this);
if (--countDown == 0)
return;
}
}
}
public static void main(String[] args)
{
new SimplePriorities(Thread.MAX_PRIORITY);
for (int i = 0;i < 5;i++)
{
new SimplePriorities(Thread.MIN_PRIORITY);
}
}
}