Java中实现多线程的方法的两种方式
- 继承Thread类
- 实现Runnable接口
由于Java是单继承多实现,因此第一种继承Thread类会用一定局限性
线程的生存周期
注:图片来自网络(若侵则删)
图解
- 创建:当new Thread()时则线程被创建
- 就绪:当调用start()方法时线程处于就绪状态,此时的线程并不一定是已经被执行,此时CPU有可能正在执行其 他线程
- 运行:线程获取到CPU资源执行Run()方法里面的代码,进入运行状态
- 终止:Run()方法中代码执行完毕,终止线程。
- 阻塞状态:阻塞的情况,如果在Run()方法中加入了wait()/join()/sleep()等方法,此时线程处于阻塞状态, 将让出CPU资源给其他线程,在该线程被唤醒之后将再次进入就绪状态,等待有空闲的CPU资源。
Runnable的代码可以被多个线程(Thread实例)共享,适合多个线程处理同一资源的问题,而继承Thread类不会,用两种方式写个例子证明一下
使用继承Thread类
/**
* @Author: www.itze.cn
* @Email: 814565718@qq.com
*/
class MyThread extends Thread {
private int number = 3;//剩余票数
@Override
public void run() {
while (number > 0) {
number--; //假设每次执行减少一张票数
System.out.println("线程名:" + Thread.currentThread().getName() + "剩余票数:" + number);
}
}
}
public class ThreadAndRunnable {
public static void main(String[] args) {
//创建3个线程
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
MyThread myThread3 = new MyThread();
//启动
myThread1.start();
myThread2.start();
myThread3.start();
}
}
继承Thread类执行结果
使用实现Runnable接口
/**
* @Author: www.itze.cn
* @Email: 814565718@qq.com
*/
class MyThread2 implements Runnable {
private int number = 3;//剩余票数
@Override
public void run() {
while (number > 0) {
number--;
System.out.println("线程名:" + Thread.currentThread().getName() + "剩余票数:" + number);
}
}
}
public class ThreadAndRunnable {
public static void main(String[] args) {
//创建3个线程
MyThread2 thread = new MyThread2();
Thread thread1 = new Thread(thread);
Thread thread2 = new Thread(thread);
Thread thread3 = new Thread(thread);
//启动
thread1.start();
thread2.start();
thread3.start();
}
}
实现Runnable接口执行结果
注:线程的启动顺序并不一定是线程的执行顺序!要看哪个线程优先抢占到CPU资源!
由两者的执行结果可以证明上面的结果,Runnable的代码可以被多个线程(Thread实例)共享,继承Thread类的方式每个线程都执行了3次,实现Runnable接口的所有线程执行了3次。这里不考虑同步。