一、前言
多线程 的创建方式主要有以下几种:
- 继承Thread类创建 线程 ;
- 实现Runnable接口;
- 使用Callable和Future创建;
- 使用 线程池 。
本篇文章我们主要了解Thread类和Runnable接口。
二、Thread和Runnable简介
Thread是一个类,作用是用来实现多线程的。Thread本身就实现了Runnable接口,它的声明如下:
public class Thread implements Runnable {}
Runnable是一个接口,作用也是用来实现多线程的。该接口中只包含一个run()方法,它的定义如下:
public interface Runnable {
public abstract void run();
}
Thread和Runnable的相同点都是用来实现多线程的,不同之处在于Thread本身是一个实现了Runnable接口的类,而Runnable只是一个接口定义。
我们知道“一个类只能有一个父类,但是却能实现多个接口”,因此Runnable具有更好的扩展性。此外,Runnable还可以用于“资源共享”,即多个线程都是基于同一个Runnable对象建立的,它们会共享Runnable对象上的资源。
三、Thread和Runnable实现多线程示例
1、Thread的多线程示例
以网上举例最多的卖票为例:
public class ThreadTest {
public static void main(String[] args) {
// 启动3个线程t1,t2,t3;每个线程各卖10张票!
TestThread t1 = new TestThread();
TestThread t2 = new TestThread();
TestThread t3 = new TestThread();
t1. start ();
t2.start();
t3.start();
}
}
class TestThread extends Thread {
private int ticket = 10;
@ Override
public void run() {
for (int i = 0; i < 20; i++) {
if (this.ticket > 0) {
System.out.println(this.getName() + " 卖票:ticket" + this.ticket--);
}
}
}
};
运行结果如下图:
结果说明:
- TestThread继承于Thread,它是自定义个线程。每个TestThread都会卖出10张票。
- 主线程main创建并启动3个TestThread子线程。每个子线程都各自卖出了10张票。
2、Runnable的多线程示例
class TesTestThread implements Runnable {
private int ticket = 10;
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName() + " 卖票:ticket" + this.ticket--);
}
}
}
};
public class RunnableTest {
public static void main(String[] args) {
TesTestThread mt = new TesTestThread();
// 启动3个线程t1,t2,t3(它们共用一个Runnable对象),这3个线程一共卖10张票!
Thread t1 = new Thread(mt);
Thread t2 = new Thread(mt);
Thread t3 = new Thread(mt);
t1.start();
t2.start();
t3.start();
}
}
运行结果如下图:
结果说明:
- 和上面“TestThread继承于Thread”不同;这里的TestThread实现了Thread接口。
- 主线程main创建并启动3个子线程,而且这3个子线程都是基于“mt这个Runnable对象”而创建的。运行结果是这3个子线程一共卖出了10张票。这说明它们是共享了TestThread接口的。