我在tutorial website上找到了这段代码:
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
在下面一行中,参数的目的是什么,this
在第一个参数中的含义是什么:
t = new Thread(this, "Demo Thread");
此代码的预期行为(流程)是什么?
答案 0 :(得分:0)
行t = new Thread(this, "Demo Thread")
正在创建一个新线程,该线程传递线程应该执行的java.lang.Runnable
实例以及给予线程的名称(在日志记录操作期间常用)。
让实现java.lang.Runnable
的类创建线程本身有点奇怪。看一下如何在java.lang.Thread的JavaDoc上使用线程的示例。
答案 1 :(得分:0)
t = new Thread(this, "Demo thread")
中使用的构造函数允许传递目标。目标必须是Runnable。作为启动run()
的结果,将调用目标的t
方法,因此创建并运行Thread。请参阅documentation
答案 2 :(得分:0)
创建新的Thread
对象时,必须传入Runnable
对象(在run()
方法中执行实际工作)作为构造函数的第一个参数。第二个参数是线程的名称。因此,在您的代码中,NewThread
类构造函数中的以下行:
t = new Thread(this, "Demo Thread");
使用自身(Thread
的实例)作为t
任务创建一个名为 Demo Thread 的新NewThread
对象Runnable
,因为它实现Runnable
接口。然后,当调用t.start()
时,将调用run()
实例NewThread
的{{1}}方法。
java.lang.Thread和java.lang.Runnable的API文档提供了更多详细信息。
因此,您的代码创建了一个t
对象,它在运行子线程循环的构造函数中启动子线程,而主线程循环是由NewThread
方法中的其余代码执行。我希望看到子线程的输出在运行时与主线程的输出交错。
此外,在捕获main()
而不是重新抛出它时,最好还原线程的中断的状态,如下所示:
InterruptedException
如果您想了解有关Java线程的更多信息,Brian Goetz的这个tutorial非常好。它是IBM developerWorks Java concurrency培训模块的一部分。
答案 3 :(得分:0)
那是一些严重混乱的代码。 OP,你没有写这个,但你只是因为磕磕绊绊而加热。
首先:NewThread不是一个线程,它是一个Runnable。不一样,也是有原因的。但是它的构造函数声明了一个新线程并且立即启动它,将Runnable变成某种Zombie Thread,这违背了在Runnable中使用Runnable的全部目的。第一个地方,这只是一个可怕的想法,因为如果你想要一个线程,你会声明一个线程,而不是一个Runnable。如果你想在ThreadPool中使用Runnable怎么办?如果您想要定义多个Runnable并以有序的方式启动它们,该怎么办?如果Runnable有一天变成Callable,你会在哪里看到它的未来呢?
然后,为了增加对伤害的侮辱,代码在主线程中具有并发代码。这个服务器没有教育目的,几乎没有现实生活价值,因为在现实生活中,你通常不会混合那样的线程代码,你宁愿有一个控制线程(主)和1..n工作线程(由主要人控制。
Threads和Runnables的意思是将任务的功能描述(即Runnable)与生命周期行为(即Thread)分开。并行执行和可伸缩性是一个很好的附带好处。因此,让我们重构教程代码以反映:
class Countdown implements Runnable {
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo2 {
public static void main(String args[]) {
Thread t = new Thread(new Countdown());
t.start();
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
那更好。现在,Runnable不再伪装成一个Thread,也不关心它何时,如何以及由谁运行。它所做的只是实现run(),它执行任务应该做的事情,主线程将此Runnable作为新Thread的构造函数参数,然后start()s,这反过来意味着新线程将调用Runnable的run()。但是我们可以做得更好:两个线程基本上做同样的事情,所以我们应该这样实现它们:
class Countdown implements Runnable {
final String name;
final int length;
final int skip;
public Countdown(String name, int length, int skip) {
this.name = name;
this.length = length;
this.skip = skip;
}
public void run() {
try {
for(int i = length; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(skip);
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println("Exiting " + name);
}
}
public class ThreadDemo3 {
public static void main(String args[]) {
Thread t1 = new Thread(new Countdown("Child One", 5, 50));
Thread t2 = new Thread(new Countdown("Child Two", 5, 100));
t1.start();
t2.start();
}
}
现在我们将功能与生命周期管理分开了。倒计时是它自己的类,它完全按照名称所说的而不是更多,并且主要没有更多的工作逻辑。 Main只是调用倒计时并启动它们。
OP,我最大的建议是:找一个更好的教程。上面grkvlt提到的Brian Goetz教程很多更好。您可能希望通过Goetz(“Java Concurrency in Practice”)和Doug Lea(“Java中的并行编程”)在书籍上投入一些资金。