线程类问题求解

CeleronWind 2003-07-30 11:20:11
问题如下:
24. What will be the output on compiling/running the following code?
public class MyThread implements Runnable {
String myString = "Yes ";
public void run() {
this.myString = "No ";
}
public static void main(String[] args) {
MyThread t = new MyThread();
new Thread(t).start();
for (int i=0; i < 10; i++)
System.out.print(t.myString);
}
}
A. compile error
B. prints: yes yes yes yes yes yes and so on
C. prints: no no no no no no no no and so on
D. prints: yes no yes no ye no ye no and so on
E. the output cannot be determinated

我的答案是C
标答是E
解释如下:
24. E is correct. Please note that there will not be any compilation error when the above code is compiled. Also note that calling start() method on a Thread doesn't start the Thread. It only makes a Thread ready to be called. Depending on the operation system and other running threads, the thread on which start is called will get executed. In the above case it is not guaranteed that the thread will be executed(i.e. run() method will be called), always before "for" loop is executed. Thus the output cannot be determined.

没看明白,难道线程不是独立于平台的吗?谁能详细解释一下?
...全文
156 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
iceyou 2003-09-17
  • 打赏
  • 举报
回复
up
wu4long 2003-08-23
  • 打赏
  • 举报
回复
我不想再说了,上面说的 很好,Thread中start()方法的调用还是在主线程中,
所以肯定先执行,后来调用run(),是开启新的线程,所以它的执行顺序不可
预知,如果,你想等一个线程执行完后,在执行,用t.join();即可
lfh159257 2003-08-20
  • 打赏
  • 举报
回复
UP
luoyuanfan 2003-08-19
  • 打赏
  • 举报
回复
有道理,谢了!
zhirenshao 2003-08-19
  • 打赏
  • 举报
回复
Sorry, 上面有一个地方打错,在我论述的第二段的第5个字应该是 10
而不是24
zhirenshao 2003-08-19
  • 打赏
  • 举报
回复
为了方便阅读,我把两题拷贝下来:
24
----
1. public class MyThread implements Runnable {
2. String myString = "Yes ";
3. public void run() {
4. this.myString = "No ";
5. }
6. public static void main(String[] args) {
7. MyThread t = new MyThread();
8. new Thread(t).start();
9. for (int i=0; i < 10; i++)
10. System.out.print(t.myString);
11. }
12. }


10
----
1. class MyThread extends Thread {
2. public void run(){
3. System.out.println("MyThread: run()");
4. }

5. public void start(){
6. System.out.println("MyThread: start()");
7. }
8. }

9. class MyRunnable implements Runnable{
10. public void run(){
11. System.out.println("MyRunnable: run()");
12. }

13. public void start(){
14. System.out.println("MyRunnable: start()");
15. }
16. }

17. public class MyTest {
18. public static void main(String args[]){
19. MyThread myThread = new MyThread();
20. MyRunnable myRunnable = new MyRunnable();
21. Thread thread = new Thread(myRunnable);
22. myThread.start();
23. thread.start();
24. }
25. }


是这样的:第10题和第24题的不同之处在于:在第10题的中,类MyThread将public void start()重写了。 你在main里面用
MyThread myThread = new MyThread();
新建了一个对象,当你调用myThread.start()的时候,系统不会新开一个线程,而只是简单地调用那个你自己定义的public void start() .

所以请看24题的第22行,22行只是一个简单的方法调用,这时候还只有一个线程--main线程,直到第23行,第二个线程才被启动,所以MyThread: start() 一定会先被打印出来,当第二个线程启动后,MyRunnable:run()才被打印出来。

而第24题呢,由于start()没有被重写,默认的start()行为是新开一个线程,用这个线程来运行run()方法。 所以在第8行的时候第二个线程就启动了,这时候是在你打印任何东西之前。 然后就是两个线程一起运行,所以你无法确定到底哪个先被打印出来。
luoyuanfan 2003-08-18
  • 打赏
  • 举报
回复
所以我觉得第二题的答案还有待斟酌。
luoyuanfan 2003-08-18
  • 打赏
  • 举报
回复
这里有一个疑问。实际上main()方法也是一个线程。那么myThread.start();就有可能在System.out.println("MyRunnable: run()");后面执行。
不妨试着运行下面的例子:
class Thread1 extends Thread
{
int threadNumber;
public Thread1(int i)
{
threadNumber=i;
}
public void run()
{
for(int i=0;i<2;i++)
System.out.println(" Running thread 1 number=" + threadNumber);
}
}
class Thread2 extends Thread
{
int threadNumber;
public Thread2(int i)
{
threadNumber=i;
}
public void run()
{
for(int i=0;i<2;i++)
System.out.println(" Running thread 2 number=" + threadNumber);

}
}
public class TwoThread1
{
public static void main(String[] args)
{
new Thread1(1).start();
new Thread1(2).start();
new Thread2(1).start();
new Thread2(2).start();
System.out.println(" End of main");
}
}
结果有多种,比如下面两种:

Result 1: Result 2:

End of main Running thread 1 number=1
Running thread 1 number=1 Running thread 1 number=1
Running thread 1 number=1 Running thread 1 number=2
Running thread 1 number=2 Running thread 1 number=2
Running thread 1 number=2 End of main
Running thread 2 number=1 Running thread 2 number=1
Running thread 2 number=1 Running thread 2 number=1
Running thread 2 number=2 Running thread 2 number=2
Running thread 2 number=2 Running thread 2 number=2
lbblbb008 2003-08-16
  • 打赏
  • 举报
回复
不是不调用,而是不是立即调用.
第一题:正是因为线程的这种特性,所以在第一题中我们不能确定他的输出.
第二题:重写的方法就不说了,第二个start方法是Thread本身的方法,所以他要调用run方法
所以要输出"MyRunnable:run()",而不管他是否立即执行run方法,打个比喻他就是在明天执行,他也要输出"MyRunnable:run()",字符串呀.
所以,你要把问题弄清楚!
^_^
CeleronWind 2003-08-01
  • 打赏
  • 举报
回复
谁都有起步的时候,jcheckboxsuyu(jcheckboxsuyu)也不要这样说嘛。
真正的高手是自己明白,同时也能让别人明白。比如说科普教材就不是人人都写得出来的。我也是给大家一个锻炼的机会。呵呵。
jkit 2003-07-31
  • 打赏
  • 举报
回复
其实英文解释已经说得很清楚了,new Thread(t).start(); 仅仅是使一个线程即将运行, 但是不保证它一定会立刻运行. 所以可能会在for循环运行的过程中运行, 这样结果就是不确定的. 一般是 yes ( *a times ) no ( *(10-a) times ) (其中0 <= a <= 10)
jcheckboxsuyu 2003-07-31
  • 打赏
  • 举报
回复
这种水平你也不用考scjp了,过了也是侥幸
Javms 2003-07-31
  • 打赏
  • 举报
回复
对于第二个问题
既然myThread的start()方法确实被重写了,实际上我们不可以把它看作一个线程运行,可以看作一个普通方法的运行!因此直接打印了MyThread: start()
而MyRunnable实现的是Runnable接口,因此虽然他也有start方法,但是这个方法永远不会被调用!因为thread.start()的方法中对于实现Runnable接口的类是这样调用的
public start()
{
...
target.run()
...
}
这个target对象就是Thread thread = new Thread(myRunnable);通过这个构造函数保存着一个对MyRunnable对象的引用!
CeleronWind 2003-07-31
  • 打赏
  • 举报
回复
myThread的start()方法确实被重写了。但是thread.start()调用的还是Thread本身的方法呀,那样的话,MyRunnable:run()有可能是不会显示的。
Javms 2003-07-31
  • 打赏
  • 举报
回复
你的理解有问题,后一题中重写了thread的start()方法,而start方法默认实现是会调用run方法,你应该这样理解,start()执行后需要进行一些创建线程的初始化动作,但run方法却并未立即调用,所有有前后两题的不同!
CeleronWind 2003-07-31
  • 打赏
  • 举报
回复
那如果是这种理解方式,那么下面这道题怎么解释?


10. What will happen when you attempt to compile and run the following code?

class MyThread extends Thread
{
public void run()
{
System.out.println("MyThread: run()");
}

public void start()
{
System.out.println("MyThread: start()");
}
}

class MyRunnable implements Runnable
{
public void run()
{
System.out.println("MyRunnable: run()");
}

public void start()
{
System.out.println("MyRunnable: start()");
}
}

public class MyTest
{
public static void main(String args[])
{
MyThread myThread = new MyThread();
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
myThread.start();
thread.start();
}
}

Choices:
a. Prints : MyThread: start() followed by MyRunnable:run()
b. Prints : MyThread: run() followed by MyRunnable:start()
c. Prints : MyThread: start() followed by MyRunnable:start()
d. Prints : MyThread: run() followed by MyRunnable:run()
e. Compile time error
f. None of the above


这道题的答案是A,估计大家都基本不会选错。

但是如果说myThread.start();
thread.start();
后,也是只表示线程即将运行,而不保证一定会运行。那么就有可能println出来的内容为空,答案A就不对了呀。
mayanwei 2003-07-30
  • 打赏
  • 举报
回复
output cannot be determinated--------输出不确定

表示this.myString = "No ";不能被知道将在何时执行~

比如有可能会在for循环的过程中myString被赋值成"no"

其输出结果就变成了"yes yes yes yes no no no no "

51,395

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧