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 方法启动线程。