在java语言中,线程和其他所有元素一样,都是对象。java提供了两种方式来创建线程:
- 继承Thread类,并重写run()方法;
- 在类中实现Runnable接口,并实现run()抽象方法。使用带参数的Thread构造方法来创建Thread对象。该参数就是实现runnable接口的类的一个对象。
继承Thread类的实现:
public class Calculator extends Thread {
private int number;
public Calculator(int number){
this.number = number;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i =1; i<=10;i++){
System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(),number,i,i*number);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=1; i<=10; i++){
Calculator calculator = new Calculator(i);
calculator.start();//子类对象调用调用父类方法,另外在Thread类的start()方法实现中,也调用了run()方法,在run()重写后则重写后的代码被调用
}
}
}
实现Runnable接口的实现:
public class Calculator implements Runnable {
private int number;
public Calculator(int number){
this.number = number;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i =1; i<=10;i++){
System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(),number,i,i*number);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=1; i<=10; i++){
Calculator calculator = new Calculator(i);
Thread thread = new Thread(calculator);//将实现Runnable接口的类的对象作为参数,新建Thread对象
thread.start();
}
}
}
对比:
从代码形式上看实现相同的功能,二者仅在main方法中有细微差别。
但由于Java不支持多继承,因此继承Thread类后不能再继承其他类。另外,两种实现方法其实都对run()方法进行了重写,
run()方法指定了线程具体要做的操作。
Thread类本身是Runnable接口的一个实现,而Runnable接口中只有一个run()的声明。在Thread类的start()方法中,除了一些操作外就是调用了run()方法。附上源码就明白了。
//Thread对象中对run()方法的实现
@Override
public void run() {
if (target != null) {
target.run();//target是一个实现了Runnable的类实例,比如上面的calculator对象
}
}
Thread类中的start()方法:
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();//调用native方法,执行run()方法