创建线程
继承Thread类
public class MyThread extends Thread {
public void run() {
// 线程执行代码
}
}
// 使用示例
Thread t = new MyThread();
t.start();实现Runnable接口
public class MyRunnable implements Runnable {
public void run() {
// 线程执行代码
}
}
// 使用示例
Thread t = new Thread(new MyRunnable());
t.start();实现Callable接口(带返回值)
Warning
前两种存在的问题:假如线程执行完毕后有一些数据需要返回,他们重写的run方法均不能直接返回结果。
import java.util.concurrent.*;
public class BasicCallableDemo {
public static void main(String[] args) throws Exception {
// 1. 创建Callable任务
Callable<String> task = () -> {
Thread.sleep(1000);
return "任务执行完毕";
};
// 2. 包装成FutureTask
FutureTask<String> future = new FutureTask<>(task);
// 3. 直接启动线程(不用线程池)
new Thread(future).start();
// 4. 获取结果(会阻塞)
System.out.println(future.get()); // 输出: 任务执行完毕
}
}
线程的常用方法
基础控制方法
start(): 启动线程run(): 线程执行体(需重写)sleep(long millis): 线程休眠指定毫秒(静态方法)yield(): 暂停当前线程,让出CPU(静态方法)
状态检查方法
isAlive(): 判断线程是否存活isDaemon(): 判断是否为守护线程getState(): 获取线程状态(NEW/RUNNABLE/BLOCKED等)
中断相关
interrupt(): 中断线程isInterrupted(): 判断是否被中断interrupted(): 判断并清除中断状态(静态方法)
其他
setPriority(int): 设置线程优先级(1-10)setDaemon(boolean): 设置守护线程join(): 等待该线程终止currentThread(): 获取当前线程(静态方法)
线程安全
当多个线程访问共享资源时,可能出现数据不一致问题。解决方案:
- 同步代码块:
锁对象的使用规范
- 建议使用共享资源作为锁对象,对于实例方法建议使用this作为锁对象。
- 对于静态方法建议使用字节码(类名.class)对象作为锁对象。
synchronized(锁对象) {
// 临界区代码
}- 同步方法:
public synchronized void method() {
// 同步代码
}- Lock接口(更灵活):
final Lock lock = new ReentrantLock(); // 建议final修饰,防止被修改
lock.lock(); // 上锁
try {
// 临界区代码
} finally {
lock.unlock(); // 解锁
}线程同步
等待唤醒机制
// 等待
synchronized(obj) {
obj.wait();
}
// 唤醒
synchronized(obj) {
obj.notify(); // 随机唤醒一个
obj.notifyAll(); // 唤醒所有
}同步工具类
- CountDownLatch:等待多个线程完成
- CyclicBarrier:线程到达屏障时等待
- Semaphore:控制并发线程数
线程池
创建线程池
// 推荐手动创建(避免Executors的潜在问题)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(100) // 任务队列
);处理Runnable任务
executor.execute(() -> {
System.out.println("执行Runnable任务");
});处理Callable任务
Future<String> future = executor.submit(() -> {
Thread.sleep(1000);
return "Callable结果";
});
System.out.println(future.get()); // 获取返回值通过Executors创建线程池
// 1. 固定大小线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
// 2. 单线程池(保证顺序执行)
ExecutorService singleThread = Executors.newSingleThreadExecutor();
// 3. 可缓存线程池(自动扩容)
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 4. 定时任务线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
scheduledPool.schedule(() -> {
System.out.println("延迟3秒执行");
}, 3, TimeUnit.SECONDS);注意
Executors创建的线程池可能引发OOM(如CachedThreadPool任务队列无界),生产环境建议手动创建ThreadPoolExecutor
线程池参数配置公式
核心参数配置建议
CPU密集型任务(计算为主):
- 核心线程数 = CPU核数 + 1
- 最大线程数 = CPU核数 * 2
IO密集型任务(网络/磁盘IO为主):
- 核心线程数 = CPU核数 * 2
- 最大线程数 = CPU核数 / (1 - 阻塞系数)
- 阻塞系数(经验值0.8~0.9)
获取CPU核数:
int cpuCores = Runtime.getRuntime().availableProcessors();