站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题关于线程的执行顺序问题

关于线程的执行顺序问题

摘要: 关于线程的执行顺序问题


在学习thinking in java,运行其示例代码时,对其yield()方法的作用不甚了解,于是在相关部分加上打印语句
代码如下:

package c14;

// : Daemons.java
//Daemonic behavior

import java.io.*;

class Daemon extends Thread {
private static final int SIZE = 10;

private Thread[] t = new Thread[SIZE];

public Daemon() {
setDaemon(true);
start();
}

public void run() {
for (int i = 0; i -#60; SIZE; i++)
t[i] = new DaemonSpawn(i);
for (int i = 0; i -#60; SIZE; i++)
System.out.println(-#34;t[-#34; + i + -#34;].isDaemon() = -#34; + t[i].isDaemon());
// while (true)
for(int i=0;i-#60;5;i++){
System.out.println(-#34;111111111-#34;);
yield();
System.out.println(-#34;222222222-#34;);
}
}
}

class DaemonSpawn extends Thread {
public DaemonSpawn(int i) {
System.out.println(-#34;DaemonSpawn -#34; + i + -#34;started-#34;);
start();
}

public void run() {
while (true){
System.out.println(-#34;DaemonSpawn ended1-#34;);
yield();
System.out.println(-#34;DaemonSpawn ended2-#34;);
}
}
}

public class Daemons {
public static void main(String[] args) {
Thread d = new Daemon();
// System.out.println(-#34;d1.isDaemon() = -#34; + d.isDaemon());
// Allow the daemon threads to finish
// their startup processes:
/* BufferedReader stdin = new BufferedReader(new InputStreamReader(
System.in));
System.out.println(-#34;Waiting for CR-#34;);
try {
stdin.readLine();
} catch (IOException e) {
}*/
}
} ///:~

其中一次执行的结果如下:
end
DaemonSpawn 0started
DaemonSpawn 1started
DaemonSpawn 2started
DaemonSpawn 3started
DaemonSpawn 4started
DaemonSpawn 5started
DaemonSpawn 6started
DaemonSpawn 7started
DaemonSpawn 8started
DaemonSpawn 9started
t[0].isDaemon() = true
t[1].isDaemon() = true
t[2].isDaemon() = true
t[3].isDaemon() = true
t[4].isDaemon() = true
t[5].isDaemon() = true
t[6].isDaemon() = true
t[7].isDaemon() = true
t[8].isDaemon() = true
t[9].isDaemon() = true
111111111
222222222
111111111
DaemonSpawn ended1
222222222
111111111
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
222222222
111111111
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
222222222
111111111
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
222222222
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1
DaemonSpawn ended2
DaemonSpawn ended1

有哪位高人能愿帮我解此疑惑?


什么疑惑??多设些断点摸索去好


在Daemon类的run中我对yield()加了一个5次的for循环
从这5次的运行结果来看是执行了DaemonSpawn类中的run方法,而DaemonSpawn的yield方法的运行结果却不能由该结果看出
我对yield方法的用法不是很了解,查文档的解释是:暂停当前正在执行的线程对象,并执行其他线程。
我想得到得解释是:此2处yield方法运行的作用是什么?如果能从运行结果来解释就最好了。
多谢各位了!


路过.......


//----------------送个笑话-------------------

儿子问爸爸,欲火焚身是什么意思,爸爸便委婉地告诉他是某人想要什么东西的意思。



语文课上没有粉笔,年轻的女老师刚好自己要去取时,儿子就立刻站起来说;“老师,我知道你是欲火焚身,还是让我满足你吧~”

www.xiaohua007.com


当时我看这个程序时是这样理解的,仅供你参考
这个例子其实是为了说明daemon线程的生存周期,当所有的非daemon线程结束后,不论有多少daemon线程仍未结束,程序也会结束

作者为了确保所有的daemon线程(即Daemon线程本身,和其产生的所有DaemonSpawn线程)未结束,所有使用了while(true)循环,以确保它们在做些什么事情

作者在书中提到,早期版本的while循环中是对一个计时器不断加1,而这样程序运行起来会很慢,所有新版本中作者用yield()方法来替代,yield方法会使当前的线程放弃CPU的执行权,重新进入等待队列中等待其下一个时间片,这样即保证了daemon线程没有结束,也使得程序运行起来不那么慢,从程序的执行结果中,其实也看不出什么yield方法执行的痕迹


yield():线程放弃执行,使其他优先级不低于此线程的线程有机会运行。
只是定义:我的理解是多线程执行时调用START时线程进入随时运行状态,至于何时运行由虚拟机决定,虚拟机会将各个线程分成N个时间片,在线程周期内交替执行各个线程的时间片,这时某线程调用yield()方法后,虚拟机调用此线程的时间片时主动放弃执行向下执行直到调用到不比此线程优先级低的其他线程的时间片...我的理解你看看。


我的理解和楼上的不一样,yield()只能使同优先级的线程有执行的机会,因为调用了yield方法后,线程是进入了等待队列,即仍然处于可执行状态,所以调用了该方法后线程有可能因为优先级高而立即再次执行;
而sleep()才可以使优先级低的线程得到执行的机会,因为线程调用sleep(N)后是进入阻塞队列N毫秒后才再次进入等待队列,在阻塞队列中时CPU是不考虑分配其时间片的,这样低优先级的进程才可能执行

所以sleep(0)=yield(),即它们的功能是一样的


同意楼上的,因为java线程是抢占式调度
优先级高的先运行(但不是始终运行),当高优先级的线程进入终
止状态或长时间等待状态,或有更高优先级的线程



路过,友情up...


已结帖 感谢各位!


↑返回目录
前一篇: 用自己写的类加载器加载类后的问题?
后一篇: 字符串数组的比较???compareTo()的问题