线程(thread)是进程中某个单一顺序的控制流。也被称为轻量进程(lightweight processes)。计算机科学术语,指运行中的程序的调度单位。通俗的来说,线程就是程序执行的线索,每一个线程都是一条在执行的线索,线索可以有很多条,即多线程。
下面我们来看一下Java中创建线程的两种方式:
1.继承Thread类,重写父类的run()方法。
2.实现Runnable接口,实现借口中的run()方法。
下面我们通过简短的代码来看一下。
继承Thread类:
package com.alex.lip.iteye;
/**
* 继承Thread类,并且重写父类Thread中的run()方法。
*/
public class SubThread extends Thread{
@Override
public void run() {
// 写一个死循环,使线程一直处于运行状态
while (true) {
try {
// 线程睡眠500ms
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//打印输出当前线程的线程名
System.out.println("This class extends Thread====1:" + Thread.currentThread().getName());
// 在此例中,可以使用this代表当前线程的对象,不建议使用。
System.out.println("This class extends Thread====2:" + this.getName());
}
}
}
实现Runnable接口:
package com.alex.lip.iteye;
/**
* 实现Runnable接口,实现其中的run方法
*
*/
public class ThreadExtendsRunnable implements Runnable{
@Override
public void run() {
// 写一个死循环,使线程一直处于运行状态
while (true) {
try {
// 线程睡眠500ms
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//打印输出当前线程的线程名
System.out.println("This class implements Runnable====1:" + Thread.currentThread().getName());
}
}
}
测试类:
package com.alex.lip.iteye;
public class TestThread {
public static void main(String[] args) {
//=============继承Thread独享===
// 创建一个SubThread对象赋予thread1
Thread thread1 = new SubThread();
// 启动该线程
thread1.start();
//=============实现Runnable接口
// 首先创建一个ThreadExtendsRunnable对象,赋给target
Runnable target = new ThreadExtendsRunnable();
// 将Runnbale对象target当做参数传给Thread的有参构造方法
Thread thread2 = new Thread(target);
// 启动线程
thread2.start();
}
}
输出结果:
This class extends Thread====1:Thread-0
This class extends Thread====2:Thread-0
This class implements Runnable====1:Thread-1
This class extends Thread====1:Thread-0
This class extends Thread====2:Thread-0
This class implements Runnable====1:Thread-1
注:由于是死循环输出,故输出结果很多,在此仅截取一部分结果为例。
下面我们通过源代码来看一下,为什么会有这两种创建线程的方式。大家都知道,线程是通过start()方法启动的,但是线程的执行都在run()方法内,所以我们来看一下Thread类中的run()方法,代码如下:
@Override
public void run() {
if (target != null) {
target.run();
}
}
在run方法中,就简短的两行代码,如果target不为null,则执行target.run()方法。通过查看源代码可以发现,target是一个Runnbale对象。那么在创建线程的过程中也就有了这两种方式,1.继承Thread类,重写run()方法,那么在调用start()后就会调用到子类中重写的run()方法,如果子类没有重写run()方法,那么就会调用父类的run()方法,代码如上,此时即会调用到实现Runnbale接口的对象中实现的的run()方法。所以就会有这两种方式来创建线程。但是此时会有一个疑问,假如这两种方式都存在会怎么样呢?我们看如下的例子。
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Runnable===1:" + Thread.currentThread().getName());
}
}
}) {
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread===1:" + Thread.currentThread().getName());
}
};
}.start();
运行结果如下:
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
如果子类中不重写run()方法,则同上面举过的Runnable的例子,这里就不再举例。
注:个人水平有限,如果文中存在不正确地方,希望大家指出,谢谢!