如何覆盖java中的thread.start()方法?
我需要在我的java代码中实现thread.start()方法。 请通过覆盖thread.start()方法以及它如何工作的示例告诉我?
你不应该。 改为覆盖运行
正如其他人所说,重写Thread.start()
不是这样做的。 通常,我也不会覆盖Thread.run()
,但使用Runnable
。
如果你必须决定在生成线程后运行哪种方法,你可以这样做:
final Runnable runnableA = ...; final Runnable runnableB = ...; Runnable r = new Runnable() { @Override public void run() { if (...) { runnableA.run(); } else { runnableB.run(); } } } Thread thread = new Thread(r); thread.start();
如果,如你所说,你有一个超类和子类,其中run()
方法被覆盖,你可以只依赖后期绑定,并自动调用适当的方法:
Runnable couldBeAOrB = ...; Thread thread = new Thread(couldBeAOrB); thread.start();
您可以像任何其他方法一样覆盖start
Thread myThread = new Thread() { @Override public void start() { // do something in the actual (old) thread super.start(); } @Override public void run() { // do something in a new thread if 'called' by super.start() } };
但是你必须调用super.start()
来创建一个新线程,并在该新线程中调用run()
。 最初的start
做了一些你几乎无法模仿的魔法 (本机代码)。
如果直接从start()
(或任何其他方法)中调用run()
,它将在实际线程中作为普通方法执行,而不是在新线程中执行。 如果您不想在新线程中运行某些代码,则没有理由使用Thread。
您必须将您的决策逻辑放在run()
方法中,如果确实需要,可以在构造函数(或其他方法,最终在start
)中使用一些变量集。 我找不到任何需要这个变量的理由,它应该足以在其他地方已经建议的run()
测试条件。
class MyThread extends Thread { private final boolean flag; public MyThread(boolean someCondition) { flag = someCondition; } // alternative // @Override // public synchronized void start() { // flag = <> // super.start(); // } @Override public void run() { if (flag) { // do something like super.run() } else { // do something else } } }
但是如果你像@Henning建议的那样去理解和维护会更容易!
它也是一个更面向对象的解决方案……
实际上,您可以调用run()来运行线程而不是start()来运行线程。 但是有一点不同。
假设您创建了两个线程:
Thread t1 = new Thread(); Thread t2 = new Thread();
情况1:如果你一个接一个地调用“t1.run()”和“t2.run()”,它们将同步( 顺序 )开始运行t1和t2。
情况2 :如果你一个接一个地调用“t1.start()”和“t2.start()”,它们将调用它们的run()方法并开始异步( 并行 )运行t1和t2。
你没有覆盖开始,你重写“运行”。 您只需通过以下方式实现一个线程:
new Thread() { public void run() { //your code here } }.start(); //start will call the logic in your run method
同意Schildmeijer,不要覆盖start,重写run()。
事实上,虽然start可以被覆盖(它不是最终的),但它调用本机start0方法,这反过来将导致VM调用run方法(实际上来自本机线程/进程的上下文)。 本机start0方法具有私有访问权限,因此即使您覆盖了开始,我也看不到如何重现该影响。
调用start()的客户端在一个线程内(比如说,主线程),直到run方法完成它的东西才会产生另一个线程。
在http://download.oracle.com/javase/tutorial/essential/concurrency/index.html上查看关于线程的Sun(ahem,Oracle)教程,特别是有关启动线程的部分。
class Worker实现Runnable {
public void run(){if(“foo”){runFoo(); } else {runBar(); }}
private void runFoo(){// something}
private void runBar(){// else}
}
我很确定,你不需要覆盖start-Method。
顺便说一下:看看java.util.concurrent.Callable
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
是的,可以覆盖start()方法。
但它不应该被覆盖,因为它在线程类中的实现具有创建新的可执行线程的代码并且是专门的。
如果我们提供自己的start方法实现,那么它将像普通方法调用一样工作,并且只能在当前线程堆栈上工作。 将不会创建新线程。