Thread 类的使用
Thread 类是 Java 提供的线程类,每个 Thread 类对象实例在执行时会对应到一个操作系统线程,其中 Thread 类对象实例的执行是通过调用其 start 方法来启动的。
在启动执行之后,对应的操作系统线程会执行该Thread类对象实例的 run 方法,默认情况下 Thread 类的 run 方法什么都不做,故需要继承 Thread 类并重写 run 方法来定义业务逻辑。
线程的名字
Java主线程的名字为 main,子线程的名字为 Thread-1、2、3,通过Thread 类的构造函数实现自定义命名: Thread myThread = new Thread("myThread");
对于子线程来说,一般都需要定义子线程的名字,从而方便跟踪线程的执行。
线程等待 join
如果某个线程需要等待其他线程的执行结果,从而在该线程进一步汇总处理,就需要在该线程通过子线程的对象实例来调用其 join 方法,使得线程阻塞等待,直到子线程执行完成才返回。
public static void main(String[] args) {
try {
// 线程1
Thread thread1 = new MyThread();
// 线程2
Thread thread2 = new MyThread();
// 子线程并行计算
thread1.start();
thread2.start();
// 主线程等待子线程执行完成
thread1.join();
thread2.join();
System.out.println("Main do something");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
线程暂停 sleep 与 yield
二者均为 Thread 类的静态方法。
- sleep 方法可以暂停指定时间。 线程在调用 sleep 休眠之后,是可以被其他线程中断的,
- yield 方法是使调用该方法的线程让出CPU资源,然后让同等优先级的线程去竞争获取CPU资源来执行,包括调用 yield 方法的线程本身。
线程协作 wait/notify
生产者消费者模型:
基于Object 类的 wait 和 notify 方法来实现线程之间的协作
Runnalbe 接口的使用
通过继承 Thread 类和重写其 run 方法来定义业务逻辑的这种做法,将业务逻辑和 Thread 类耦合在一起,增加了耦合度。此外,Java单继承特性导致该子类无法复用其他类的代码。
为了解决以上两个问题,使用 Runnable 接口来实现 Thread 类和业务逻辑的解耦。
定义一个 Runnable 接口的实现类,重写 Runnable 的 run 方法。然后在主线程中创建该实现类的一个对象实例,并将该对象实例作为 Thread 类的构造函数参数来创建 Thread 类对象实现,最后直接调用 Thread 类的 start 方法启动线程。