Java语言中的线程系统是自建的,有专门支持多线程的API,所以我们可以快速地编写一个支持线程的程序。
我们通常可以通过继承类Thread和实现Runnable接口这两种方法来创建线程。实现线程,最重要的是实现其中的run方法。
1.继承Thread类创建线程
2.实现Runnable接口创建线程
public class ThreadTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread threadA = new Thread(new MyRunnable("A"));
MyThread threadB = new MyThread("B");
threadA.start();
threadB.start();
}
}
class MyThread extends Thread {
private String name;
public MyThread(String n) {
name = n;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("access: " + name);
}
}
}
class MyRunnable implements Runnable {
private String name;
public MyRunnable(String n) {
name = n;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("access: " + name);
}
}
}
3.两种创建线程方法的比较
Thread是Java已经严格封装好的类,在面向对象思想中,继承这样的类并修改或者扩充它并不是十分可取,因为可能出现认为失误,对一个类进行继承修改或扩充将可能导致该子类出现不可预料的错误。
另外,由于Java不支持多重继承,一个继承了Thread的类将无法再继承其他类,因为在某些情况下只能采用实现Runnable的方式,例如要实现多线程的Applet则必须通过实现Runnable创建线程。
实现Runnable方式的缺点在于,在run()方法中如果要调用当前线程自身的方法,必须先通过调用Thread.currentThread()以获得对当前线程自身的引用,而在继承自Thread方式时,可以直接调用当前线程自身的方法,后者为代码的编写带来一个一定的便利,但这点便利与上述可能造成的不可预料的错误相比,不具有太大的意义。因此如果没有绝对的把握保证继承Thread类的子类的正确性和完整性,建议采用实现Runnable的方式创建线程。
然而,实现Runnable方式并不一定总是最好的,例如要获得拥有特殊功能的线程必须通过继承并扩充Thread实现,此时若对Thread类的修改或扩充并不大,并希望保证其正确性和完整性,则更应该采用继承Thread的方式。
在实际应用中,应该根据实际情况,权衡两种方式带来的影响,选择最合适的方式。