最近在学Java多线程,看到有些文章(http://mgc.name/article.asp?id=827)理解有误,又不能在原页面发表评论,特记录之.
其中讨论了一道SCJP试题
Which two code fragments will execute the method doStuff() in a separate thread? (choose two)
A. new Thread () {
public void run() { doStuff(); }
};
B. new Thread () {
public void start() { doStuff(); }
};
C. new Thread() {
public void start() { doStuff(); }
}.run();
D. new Thread() {
public void run() { doStuff(); }
}.start();
E. new Thread (new Runnable() {
public void run() { doStuff(); }
}).run();
F. new Thread (new Runnable() {
public void run() { doStuff(); }
}).start();
题目问那两个选项将创建一个新线程执行doStuff方法.该文章说答案有三个:D、E(其实这个答案是错的)、F
说明如下:
E并不会创建新的线程.E中只有一个线程:主线程main.E中,主线程直接调用run()方法输出”doStuff”(并不是输出”doStuff”就表示创建新的线程).直接调用run()函数,这只是调用一个方法而已,程序中依然只有主线程–这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的.只有start()函数才会真正创建新线程.在调用start()的时候,start()函数会首先进行与多线程相关的初始化(这也是为什么不能直接调用run()函数的原因),然后再调用run()函数.测试代码如下:
public class MyRunnable { public static void doStuff() { System.out.println("doStuff"); } public static void main(String[] args) throws Exception{ new Thread(new Runnable() { public void run() { try { Thread.currentThread().sleep(10);//注1 } catch (InterruptedException e) { e.printStackTrace(); } doStuff(); } }).start();//注2 System.out.println("hello"); } }
我在测试代码中让新创建的线程等待10ms后执行.如果创建子线程成功,”doStuff”就会在”hello”之后输出.否则程序只有一个线程,即主线程.程序只有一条执行线路:顺序执行,主线程等待10ms,然后依次输出”doStuff”,”hello”(“Stuff”在”hello”之前输出)
—————————————————–
<注>
1:让当前线程等待10ms.如果下面是start(),新创建线程等待10ms.若是run()的话,没有创建新线程,只有一个线程:主线程,主线程等待10ms
2:此处用start(),程序创建新线程,然后新线程等待至少10ms,这10ms里主线程先输出”hello”,然后新创建的子线程运行输出”doStuff”.如果用run(),并没有创建新线程.程序只有一个主线程顺序指向,先调用run()函数,然后主线程等待10ms,然后输出”doStuff”,最后输出”hello”.程序只有一条 线.只能顺序执行,先输出”doStuff”,再”hello”