我想了解下面的程序。如果我调用new ReaderThread().start()
它工作正常,但如果我调用new ReaderThread().run()
,应用程序将进入无限循环。有什么区别?
public class Contention {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready){
System.out.println("ready ..."+ready);
Thread.yield();}
System.out.println(number);
// }
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new ReaderThread().run();
number = 42;
ready = true;
}
}
答案 0 :(得分:11)
当你在同一个帖子中调用run()
时。它只是一个方法调用。
当您致电start()
以触发另一个线程来呼叫run()
这是扩展Thread不是一个好主意的原因之一,而是实现了用线程包装的Runnable。这是许多潜在混淆的原因之一。
这是一个相关的预告片
static String name = "Peter Lawrey";
static String state = "Washington";
static String getName() {
return name;
}
static String getState() {
return state;
}
static class NamedThread extends Thread {
@Override
public void run() {
System.out.println(getName()+" - "+getState());
}
}
public static void main(String... args) throws InterruptedException {
new NamedThread().start();
}
打印
Thread-0 - RUNNABLE
你能找出原因吗?
答案 1 :(得分:4)
run()
只是一种无法启动新主题的方法 - 因此main()
永远不会将ready
设置为true
。
只有start()
实际上会产生一个单独的执行线程 - 这就是你需要的。
请注意,即使这样,由于内存模型问题,您的代码也无法保证正常工作 - 您需要担心对共享数据所做更改的可见性。
答案 2 :(得分:2)
仔细阅读java中的线程(例如http://download.oracle.com/javase/tutorial/essential/concurrency/)
当你调用方法run()时,你可以像调用任何其他方法一样调用它,它将在与调用方法相同的线程中工作。
答案 3 :(得分:2)
如果你使用new ReaderThread().start();
,你实际上是在创建一个新的线程实例,它将在后台运行,并main()
继续执行。
但是new ReaderThread().run();
创建了这个类的实例并对run()
方法进行了常规方法调用,因此main()
必须等到run()
完成执行并将控件返回给main(),在你的情况下是一个无限循环。
如果你想开始一个新的线程然后开始使用ReaderThread().start();
这是启动一个线程的正确方法,没有替代方案。
答案 4 :(得分:1)
public class Contention {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready){
System.out.println("ready ..."+ready);
Thread.yield();}
System.out.println(number);
// }
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new ReaderThread().run();//control goes to run() method
//and it keeps running and next line of code where you set ready=true will not be executed
number = 42;
ready = true;
}
}
<强>编辑:强>
因为线程不是一起运行(但是同时运行),但是OS决定运行哪一个并且它确保每个线程都基于TimeShared基础(或任何算法)获得自己的机会。所以可能在你的情况下other thread
首先获得机会并且在main()
线程有机会运行并设置ready = true.
之前执行它但是如果你再次运行你的代码,另一个案例也是可能。设置ready = true;
且Thread
不会进入While()
循环。
答案 5 :(得分:1)
当你有new ReaderThread().run();
它在同一个帖子中时,ready = true;
从未到达。
但是当你调用new ReaderThread().start()
时,它会启动一个新线程,主线程也会继续,并且会点击ready = true;
- 这将使循环中创建的线程...