java中提供了两个方法
1.通过构建Thread(java.lang.Thread)子类创建
2.通过实现Runnable(java.lang.Runnable)类创建
重写run方法
其实两者在代码编写上都差不多。都是构建个线程类,然后重写run方法。Thread和Runnable都有个成员方法
public void run ()
此方法内重写自己的业务逻辑即可。
线程启动
虽然线程的执行代码在成员方法run中,但是线程的启动或运行并不是直接调用成员方法run,而是调用类java.lang.Thread的成员方法:
public void start()
调用start方法后,java虚拟就就自动启动线程了。
1.构建Thread子类
package com.zero;
public class TestThread extends Thread {
private int times;
// 构造方法
public TestThread(int times) {
this.times = times;
System.out.println("线程" + times + "创建");
}
// 重写run方法
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("线程" + this.times + "运行中");
}
}
public static void main(String[] arges) {
// 创建两个线程
TestThread testThread1 = new TestThread(1);
TestThread testThread2 = new TestThread(2);
// 启动线程
testThread1.start();
testThread2.start();
}
}
执行结果:
第一次 第二次 第三次
注:因为线程执行具有不可预知性。所以每次的结果都不一定会一样
刚开始我以为必须是Thread的直接子类才能算线程类,后来发现只要是Thread的子类即可,无论是否为直接子类。
2.实现Runnable接口构造线程
package com.zero;
//实现Runnable接口
public class TestRunnable implements Runnable {
private int times;
//构造方法
public TestRunnable(int times) {
this.times = times;
System.out.println("线程" +times + "创建");
}
//重写run方法
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("线程" + times + "正在运行");
}
}
//main方法
public static void main (String [] args) {
//实例化线程1、2
Thread testRunnable1 = new Thread(new TestRunnable(1));
Thread testRunnable2 = new Thread(new TestRunnable(2));
testRunnable1.start();
testRunnable2.start();
}
}
运行结果:
第一次 第二次 第三次
运行结果原理其实和第一个例子是一样的。
最后说一下两种方法中对构建的线程类实例化的差别
第一种继承Thread,实例化对象时直接New一个子类即可。但是,第二种实现接口方式构建的线程类中实例化线程时会有点不一样
第二种是通过了java.lang.Thread的构造方法
public Thread(Runnabke target)
来构造Thread的实例对象,其中构造方法的target参数类型是Runnable类型的
即实例化对线(线程)语句如下(基于例子2)
Runnable Runnable3 = new TestRunnable(3);
Thread testRunnable3 = new Thread(Runnable3);
或者是
Thread testRunnable3 = new Thread(new TestRunnable(3));
当然两者的线程启动都是start方法