Java多线程基础入门
哪吒 2024/1/15
# Java多线程基础入门
点击勘误issues (opens new window),哪吒感谢大家的阅读
# 1. 什么是多线程
# 1.1 线程的概念
线程是程序执行的最小单位,一个进程可以包含多个线程。在Java中,每个线程都有自己的程序计数器、虚拟机栈和本地方法栈,但共享堆内存和方法区。
# 1.2 多线程的优势
- 提高程序响应性:用户界面不会因为后台任务而卡顿
- 充分利用CPU资源:多核CPU可以并行执行多个线程
- 提高程序吞吐量:并发处理多个任务
- 改善程序结构:将复杂任务分解为多个简单的并发任务
# 2. 创建线程的方式
# 2.1 继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.setName("线程1");
thread2.setName("线程2");
thread1.start();
thread2.start();
}
}
# 2.2 实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread thread1 = new Thread(runnable, "线程1");
Thread thread2 = new Thread(runnable, "线程2");
thread1.start();
thread2.start();
}
}
# 2.3 实现Callable接口
import java.util.concurrent.*;
public class MyCallable implements Callable<String> {
private String name;
public MyCallable(String name) {
this.name = name;
}
@Override
public String call() throws Exception {
for (int i = 0; i < 5; i++) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
return name + "执行完成";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future1 = executor.submit(new MyCallable("任务1"));
Future<String> future2 = executor.submit(new MyCallable("任务2"));
try {
System.out.println(future1.get());
System.out.println(future2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
# 2.4 使用Lambda表达式
public class LambdaThread {
public static void main(String[] args) {
// 使用Lambda表达式创建线程
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Lambda线程1: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Lambda线程2: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
}
}
# 3. 线程的生命周期
# 3.1 线程状态
Java线程有以下几种状态:
- NEW:新建状态,线程被创建但还未调用start()方法
- RUNNABLE:可运行状态,包括正在运行和等待CPU调度
- BLOCKED:阻塞状态,等待获取锁
- WAITING:等待状态,等待其他线程的通知
- TIMED_WAITING:超时等待状态,在指定时间内等待
- TERMINATED:终止状态,线程执行完毕
# 3.2 状态转换示例
public class ThreadStateDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
System.out.println("线程开始执行");
Thread.sleep(2000);
System.out.println("线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("创建后状态: " + thread.getState()); // NEW
thread.start();
System.out.println("启动后状态: " + thread.getState()); // RUNNABLE
Thread.sleep(500);
System.out.println("睡眠中状态: " + thread.getState()); // TIMED_WAITING
thread.join();
System.out.println("结束后状态: " + thread.getState()); // TERMINATED
}
}
# 4. 线程的基本操作
# 4.1 线程优先级
public class ThreadPriorityDemo {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("高优先级线程: " + i);
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("低优先级线程: " + i);
}
});
thread1.setPriority(Thread.MAX_PRIORITY); // 10
thread2.setPriority(Thread.MIN_PRIORITY); // 1
thread1.start();
thread2.start();
}
}
# 4.2 守护线程
public class DaemonThreadDemo {
public static void main(String[] args) throws InterruptedException {
Thread daemonThread = new Thread(() -> {
while (true) {
System.out.println("守护线程正在运行...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
});
daemonThread.setDaemon(true); // 设置为守护线程
daemonThread.start();
Thread.sleep(3000);
System.out.println("主线程结束");
// 主线程结束后,守护线程也会自动结束
}
}
# 4.3 线程中断
public class ThreadInterruptDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("线程正在运行...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程被中断");
Thread.currentThread().interrupt(); // 重新设置中断标志
break;
}
}
System.out.println("线程结束");
});
thread.start();
Thread.sleep(3000);
thread.interrupt(); // 中断线程
thread.join();
}
}
# 5. 线程安全问题
# 5.1 竞态条件示例
public class RaceConditionDemo {
private static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter++;
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter++;
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("最终结果: " + counter); // 可能不是20000
}
}
# 5.2 使用synchronized解决
public class SynchronizedDemo {
private static int counter = 0;
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronized (lock) {
counter++;
}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronized (lock) {
counter++;
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("最终结果: " + counter); // 确保是20000
}
}
# 6. 总结
本文介绍了Java多线程的基础知识,包括:
- 线程创建方式:继承Thread类、实现Runnable接口、实现Callable接口、使用Lambda表达式
- 线程生命周期:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
- 线程基本操作:优先级设置、守护线程、线程中断
- 线程安全问题:竞态条件和synchronized解决方案
掌握这些基础知识是学习Java并发编程的重要基础。在实际开发中,还需要深入学习线程池、锁机制、并发容器等高级主题。