Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。java 创建线程有以下几种方式
继承 Thread 类创建线程类
步骤如下:
定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务。因此把run()方法称为线程执行体
创建Thread子类的实例,即创建了线程对象
调用线程对象的start()方法来启动该线程。
public class FirstThread extends Thread {
// 线程类的成员变量 不同线程无法共享此变量
private int i;
@Override
public void run() {
for (; i < 3; i++) {
// 重写 run 方法,在线程创建时就会执行此方法
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
// 获取当前线程
System.out.println(Thread.currentThread().getName());
if (i == 2) {
// 创建并启动第1个线程
new FirstThread().start();
// 创建并启动第2个线程
new FirstThread().start();
}
}
}
}
多线程有个特征,执行的结果是不可预测的,这跟线程的生命周期有关,接下来会详解。我们启动线程时,系统并不会立即执行该线程,而是将其设为就绪状态。什么时候执行对于码农是透明的
在默认情况下,主线程的名字为main,用户启动的多个线程的名字依次为Thread-0、Thread-1、Thread-2、…、Thread-n等。
不要直接调用 run 方法
public class InvokeRun extends Thread {
private int i;
@Override
public void run() {
for (; i < 3; i++) {
// 直接调用 run 方法时,Thread 的 this.getName() 返回的是该对象的名字,而不是当前线程的名字
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 2) {
// 直接调用线程的 run 方法,会被当成普通方法,所以以下并不会启动两个线程
new InvokeRun().run();
new InvokeRun().run();
}
}
}
}