Java 线程
Java 线程
线程允许一个程序在同一时间做多件事,从而更高效地运行。
线程可以在后台执行复杂的任务,而不会中断主程序。
创建线程
创建线程有两种方法。
可以通过扩展 Thread
类并重写其 run()
方法来创建:
Extend 语法
public class Main extends Thread {
public void run() {
System.out.println("This code is running in a thread");
}
}
创建线程的另一种方法是实现 Runnable
接口:
Implement 语法
public class Main implements Runnable {
public void run() {
System.out.println("This code is running in a thread");
}
}
运行线程
如果该类扩展了 Thread
类,则可以通过创建该类的实例并调用其 start()
方法来运行该线程:
Extend 实例
public class Main extends Thread {
public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
如果类实现了 Runnable
接口,那么可以通过将类的一个实例传递给线程对象的构造函数,然后调用线程的 start()
方法来运行线程:
Implement 实例
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("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
Extend 和 Implement 线程之间的区别
主要区别在于,当一个类扩展
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++;
}
}