Java 线程

Java 线程

线程允许程序同时执行多项操作,已提升运行效率。

线程可以在不中断主程序的情况下,在后台执行复杂任务。

创建线程

创建线程有两种方法。

可通过扩展 Thread 类并覆盖其 run() 方法来创建:

扩展语法

public class Main extends Thread {
  public void run() {
    System.out.println("这段代码在一个线程中运行");
  }
}

另一种创建线程的方法是实现 Runnable 接口:

实现语法

public class Main implements Runnable {
  public void run() {
    System.out.println("这段代码在一个线程中运行");
  }
}

运行线程

如果类扩展了 Thread 类,则可以通过创建该类的实例并调用其 start() 方法来运行该线程:

扩展实例

public class Main extends Thread {
  public static void main(String[] args) {
    Main thread = new Main();
    thread.start();
    System.out.println("这段代码在线程之外");
  }
  public void run() {
    System.out.println("这段代码在一个线程中运行");
  }
}

亲自试一试

如果类实现了 Runnable 接口,则可以通过将类的实例传递给 Thread 对象的构造函数,然后调用线程的 start() 方法来运行线程:

实现实例

public class Main implements Runnable {
  public static void main(String[] args) {
    Main obj = new Main();
    Thread thread = new Thread(obj);
    thread.start();
    System.out.println("这段代码在线程之外");
  }
  public void run() {
    System.out.println("这段代码在一个线程中运行");
  }
}

亲自试一试

“扩展”和“实现”线程之间的差异

主要区别在于,当类扩展 Thread 类时,您不能扩展任何其他类,但通过实现 Runnable 接口,也可以从另一个类扩展,例如:类 MyClass extends OtherClass implements Runnable

并发问题

由于线程与程序的其他部分同时运行,因此无法获知代码将以何种顺序运行。当线程和主程序读取和写入相同的变量时,值是不可预测的。由此产生的问题称为并发问题。

实例

在下面的例子中,变量 amount 是不可预测的:

public class Main extends Thread {
  public static int amount = 0;

  public static void main(String[] args) {
    Main thread = new Main();
    thread.start();
    System.out.println(amount);
    amount++;
    System.out.println(amount);
  }

  public void run() {
    amount++;
  }
}

亲自试一试

为了避免并发问题,最好在线程之间共享尽可能少的属性。如果需要共享属性,一种可能的解决方案是使用线程的 isAlive() 方法在使用线程可以更改的任何属性之前检查线程是否已完成运行。

实例

使用 isAlive() 来防止并发问题:

public class Main extends Thread {
  public static int amount = 0;

  public static void main(String[] args) {
    Main thread = new Main();
    thread.start();
    // Wait for the thread to finish
    while(thread.isAlive()) {
    System.out.println("Waiting...");
  }
  // Update amount and print its value
  System.out.println("Main: " + amount);
  amount++;
  System.out.println("Main: " + amount);
  }
  public void run() {
    amount++;
  }
}

亲自试一试