Java多线程编程是Java应用程序中实现并发执行的关键技术。在操作系统层面,线程和进程是两个重要的概念。进程是指运行中的应用程序,每个进程都有独立的内存空间,而线程则是进程中的执行流,一个进程可以有多个线程。线程间的切换由操作系统调度,给人以“同时”执行的错觉。
在Java中,线程主要分为两种类型:用户线程和守护线程。用户线程是应用程序的主要执行部分,当所有用户线程结束时,JVM会自动关闭。守护线程则不会阻止JVM的退出,通常用于后台服务,如垃圾回收。
创建和启动Java线程主要有以下两种方式:
1. 扩展`java.lang.Thread`类。通过重写`run()`方法来定义线程的行为。例如:
```java
public class MyThread extends Thread {
public void run() {
// 线程执行的代码
}
}
```
然后通过`new MyThread().start();`来启动线程。
2. 实现`java.lang.Runnable`接口。创建一个实现了Runnable接口的类,并在`run()`方法中定义线程的行为。例如:
```java
public class MyRunnable implements Runnable {
public void run() {
// 线程执行的代码
}
}
```
然后通过`new Thread(new MyRunnable()).start();`来启动线程。
实例化线程时,可以使用`Thread`类的各种构造函数,传入`Runnable`对象或自定义线程名、线程组和堆栈大小等参数。
启动线程的关键是调用`start()`方法,而不是直接调用`run()`。`start()`方法会触发线程的执行,而`run()`方法只是一个普通方法,如果直接调用,不会创建新的执行线程。
例如,以下是一个实现Runnable接口的多线程示例:
```java
public class TestRunnable {
public static void main(String[] args) {
Thread thread1 = new Thread(new DoSomething("Thread 1"));
Thread thread2 = new Thread(new DoSomething("Thread 2"));
thread1.start();
thread2.start();
}
}
class DoSomething implements Runnable {
private String name;
public DoSomething(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
// 延迟模拟耗时操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + ": " + i);
}
}
}
```
在这个例子中,`DoSomething`类实现了`Runnable`接口,并在`run()`方法中定义了线程的行为。`TestRunnable`类的`main()`方法创建了两个线程,并调用`start()`来启动它们,这两个线程将并发执行,打印出各自的名称和循环次数。
Java多线程编程还包括线程同步、线程通信、线程安全以及线程池等高级话题。线程同步是为了避免多个线程对共享资源的竞态条件,Java提供了`synchronized`关键字、`wait()`, `notify()`, `notifyAll()`方法以及`Lock`接口等机制。线程通信是线程间交换信息的方式,例如使用`BlockingQueue`。线程安全的类和方法可以确保在多线程环境下正确工作,避免数据不一致。线程池可以提高性能,通过复用已创建的线程,减少频繁创建和销毁线程的开销。
理解并掌握Java多线程编程,对于开发高效、稳定且响应迅速的Java应用程序至关重要。在实际开发中,还需要根据具体需求选择合适的线程模型,优化并发性能,确保程序的正确性和性能。