package helloworld;
class MyThread extends Thread {
private String title;
private int ticket = 10;
public MyThread(String title) {
this.title = title;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (ticket > 0)
System.out.println(this.title + ", " + ticket--);
}
};
}
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello wolrd");
MyThread mt = new MyThread("线程A");
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}
上述代码描述的是:开启三个线程去售卖十张票。
当MyThread继承Thread类的时候,MyThread类本身也就继承了start()方法,开启线程的start为何还要new Thread去start,而不用自身的start方法呢?就相当于你自己应该写作业,偏偏你自己不写,欺负同学,让他替你写。尽管这样结果也是作业写完了,但是总有那么点不妥。
如果是实现RUnnable接口,就更好理解了:Runnable接口在jdk 1.8中源码如下:
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
可以看到函数式接口只包含有一个run方法,自己无法启动,只能通过new Thread().start()来启动。就好像你的电脑坏了,你修不了,只能去让有能力修的人修。
查看Thread的带参数的构造函数:
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
我们发现,传入的应该是一个Runnable对象,由于Thread类实现了Runnable接口,并且覆写了他的run方法
/**
* If this thread was constructed using a separate
* <code>Runnable</code> run object, then that
* <code>Runnable</code> object's <code>run</code> method is called;
* otherwise, this method does nothing and returns.
* <p>
* Subclasses of <code>Thread</code> should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
如果传入Runnable对象,那么调用他的run方法,否则什么也不做。