通过查看接口文档:
方式一:将一个类声明为 Thread 的子类,这个子类应该重写 run 类的方法 Thread。然后可以分配并启动子类的实例
方式二: 声明实现类 Runnable 接口。这个类实现 run 方法。然后可以分配类的实例,在创建Thread 时作为参数传递并启动
1、自定义类继承 Thread 类创建
步骤:
- 自定义类 MyThread 继承 Thread 类
- MyThread 类里重写 run() 方法(里面是被线程执行的那部分代码)
- 创建对象
- 调用 start() 方法启动线程
eg:从 0 开始 打印小于 100 的整数
class MyThread extends Thread {
// 重写 run() 方法
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(x);
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
// 创建线程对象
MyThread m1 = new MyThread();
MyThread m2 = new MyThread();
// 启动线程
m1.start();
m2.start();
}
}
分析:
- 关于 run() 方法:类中的代码不是都需要被线程执行的,Thread 类中华提供的 run() 方法就是那 些需要被线程执行的部分
- run() 和 start() :直接调用 run() 方法是单线程的效果,因为他仅仅只是封装线程执行的代码相当于调用普通方法。而start() 这个方法首先启动了线程,然后再由 JVM 去调用该线程的 run()
2、实现 Runnable 接口创建
步骤:
- 自定义类 MyRunnable 实现 Runnable 接口
- 重写 run() 方法
- 创建 MyRunnable 类的对象
- 创建 Thread 类的对象,并把 MyRunnable的对象作为构造参数传递
eg:
class MyRunnable implements Runnable {
public void run() {
for (int x = 0; x < 100; x++) {
//注意 getNamesh() 是实例方法,调用的时候一定要用当前线程对象
System.out.println(Thread.currentThread().getName()++"+x);
}
}
}
public class MyRunnableDemo {
public static void main(String[] args) {
//创建 MyRunnable类的对象
MyRunnable my = new MyRunnable();
//创建 Thread 类的对象,并把 my 作为构造参数传递
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
// 启动线程
t1.start();
t2.start();
}
}
两种方式的比较通过实现接口的方式更优:
首先避免了由于 java 单继承带来的局限性
同时适合多个相同程序的代码去处理同一个资源的情况,把线程同数据优先分离,体现了面型对象那个的思想