创建线程有两种方式:
1. 继承Thread类,覆写run方法;
2. 实现Runnable接口,将任务代码封装到run方法中。
1.继承Thread类创建线程
public class MyThread extends Thread{
private String name;
public MyThread(String name) {
super();
this.name = name;
}
public void finalize(){
System.out.println("垃圾回收...");
}
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(name+"....i="+i+"....thread name="+currentThread().getName());
}
}
}
public class ThreadTest {
public static void main(String[] args){
System.out.println("thread name="+Thread.currentThread().getName());
MyThread t1=new MyThread("旺财");
MyThread t2=new MyThread("小小");
t1.start();
t2.start();
}
}
2.实现Runnable接口创建线程
/*
* 创建线程的第二种方式,把线程任务单独封装成对象
*
* 实现Runnable接口的好处:
* 1.将线程的任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务封装成对象;
* 2.避免了java单继承的局限。
*
*/
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int i=0;i<10;i++)
{
System.out.println("MyRunnable....thread name="+Thread.currentThread().getName());
}
}
}
public class ThreadTest {
public static void main(String[] args){
Thread t1=new Thread(new MyRunnable());
Thread t2=new Thread(new MyRunnable());
t1.start();
t2.start();
}
}
3. 一个小问题
问题:若一个Thread子类覆盖了父类的run方法,同时也为线程传递了一个Runnable对象,则线程执行的是子类的run方法,还是Runnable对象中的run方法?
答案:执行子类的run方法。
分析如下:
public class ThreadTest {
/*
*
* 面向对象思想:先调用子类的run方法,如果没有找到子类的run方法,则再调用父类的run方法,父类的run方法会调用Runnable对象中的run方法
*
* Thread类中的run方法如下,其中target为实现Runnable接口的类的对象:
* public void run() {
* if (target != null) {
* target.run();
* }
* }
*
*/
public static void main(String[] args){
Thread thread=new Thread(new Runnable(){
public void run() {
System.out.println("runnable..........");
}
}){
//所以本例中使用的是子类中的run方法
public void run() {
System.out.println("thread....");
};
};
thread.start();
}
}