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次。这里不考虑同步。