Java多线程

Java多线程是指在一个程序中同时运行多个执行路径,可提升CPU利用率和程序响应性。以下是核心内容:
 
一、多线程实现方式
 
1. 继承 Thread 类
 
- 重写 run() 方法定义线程任务。
 
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程执行中:" + getName());
    }
}

// 使用
MyThread thread = new MyThread();
thread.start(); // 启动线程,而非直接调用run()
 
 
2. 实现 Runnable 接口
 
- 更灵活(避免单继承限制),推荐使用。
 
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable线程执行");
    }
}

// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();
 
 
3. 实现 Callable 接口(Java 5+)
 
- 支持返回值和抛出异常,需配合 Future 获取结果。
 
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        return 1 + 1; // 可返回计算结果
    }
}

// 使用
FutureTask<Integer> future = new FutureTask<>(new MyCallable());
new Thread(future).start();
Integer result = future.get(); // 阻塞获取结果
 
 
二、线程状态与生命周期
 
线程状态转换图(简化) → 运行(Running) → 阻塞(Blocked) → 等待(Waiting) → 超时等待(Timed_Waiting) → 终止(Terminated)
 
三、线程控制与常用方法
 
1. 线程调度
 
-  Thread.sleep(long ms) :让当前线程休眠指定毫秒数。
-  Thread.yield() :主动让出CPU,回到就绪状态。
-  join() :等待其他线程执行完毕,如 thread.join() 会阻塞当前线程直到 thread 结束。
 
2. 线程优先级
 
-  setPriority(int priority) :设置优先级(1-10,默认5),高优先级线程获更多执行机会。
 
3. 守护线程(Daemon Thread)
 
-  setDaemon(true) :当所有非守护线程结束时,守护线程自动终止(如垃圾回收线程)。
 
四、线程安全与同步机制
 
1. 线程安全问题
 
- 当多个线程同时访问共享资源(如变量、文件)时,可能导致数据不一致(如i++操作非原子性)。
 
2. 同步方案
 
- synchronized关键字:
- 同步代码块: synchronized(锁对象) { ... } (锁对象需为共享资源)。
- 同步方法:在方法声明前加 synchronized ,锁对象为 this 。
 
// 同步代码块示例
private Object lock = new Object();
public void safeMethod() {
    synchronized (lock) {
        // 线程安全的操作
    }
}
 
 
- ReentrantLock(可重入锁,Java 5+):
- 比 synchronized 更灵活,支持公平锁、超时等待等。
 
import java.util.concurrent.locks.ReentrantLock;

private ReentrantLock lock = new ReentrantLock();
public void safeMethod() {
    lock.lock(); // 加锁
    try {
        // 操作
    } finally {
        lock.unlock(); // 解锁(必须在finally中,避免异常导致死锁)
    }
}
 
 
3. 原子类(java.util.concurrent.atomic)
 
- 如 AtomicInteger 、 AtomicReference ,通过CAS( compare-and-swap)实现无锁原子操作:
 
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet(); // 原子性i++
 
 
五、线程通信与协作
 
1. wait/notify/notifyAll(配合synchronized)
 
-  wait() :让线程进入等待状态,释放锁。
-  notify() :唤醒一个等待中的线程。
-  notifyAll() :唤醒所有等待中的线程。
 
// 生产者-消费者示例(简化)
private final Object lock = new Object();
private int productCount = 0;

// 生产者
public void produce() {
    synchronized (lock) {
        while (productCount >= 10) { // 避免虚假唤醒,用while判断
            lock.wait(); // 等待消费者消费
        }
        productCount++;
        lock.notifyAll(); // 通知消费者
    }
}

// 消费者
public void consume() {
    synchronized (lock) {
        while (productCount <= 0) {
            lock.wait(); // 等待生产者生产
        }
        productCount--;
        lock.notifyAll(); // 通知生产者
    }
}
 
 
2. Condition(配合ReentrantLock)
 
- 比 wait/notify 更灵活,可实现多条件等待。
 
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();

public void method() {
    lock.lock();
    try {
        condition.await(); // 等待
        condition.signal(); // 唤醒一个线程
    } finally {
        lock.unlock();
    }
}
 
 
六、线程池(Java 5+,java.util.concurrent)
 
1. 核心优势
 
- 复用线程,避免频繁创建销毁线程的开销;控制线程数量,防止OOM。
 
2. 常用线程池
 
- Executors工厂方法:
-  newFixedThreadPool(int nThreads) :固定大小线程池。
-  newCachedThreadPool() :可伸缩线程池(空闲线程60秒后回收)。
-  newSingleThreadExecutor() :单线程池(按顺序执行任务)。
-  newScheduledThreadPool(int corePoolSize) :支持定时/延迟执行任务。
- 手动创建ThreadPoolExecutor(推荐,更可控):
 
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

// corePoolSize=2,最大线程数=5,空闲线程存活时间=60秒,任务队列容量=10
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    2, 5, 60, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(10),
    new ThreadFactory() { // 自定义线程创建
        private int count = 1;
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "MyThread-" + count++);
        }
    },
    new ThreadPoolExecutor.AbortPolicy() // 任务拒绝策略:默认抛出异常
);

// 提交任务
executor.execute(() -> System.out.println("异步任务"));
executor.submit(() -> { // 带返回值的任务
    System.out.println("有返回值的任务");
    return "结果";
});

// 关闭线程池
executor.shutdown(); // 平滑关闭,不接受新任务,处理完已提交任务
executor.shutdownNow(); // 立即关闭,尝试中断正在执行的任务
 
 
七、并发工具类(java.util.concurrent)
 
1. CountDownLatch
 
- 允许一个线程等待其他线程完成操作:
 
CountDownLatch latch = new CountDownLatch(3); // 初始化计数器为3

// 线程1-3完成后计数减1
new Thread(() -> { latch.countDown(); }).start();
new Thread(() -> { latch.countDown(); }).start();
new Thread(() -> { latch.countDown(); }).start();

// 主线程等待计数器归零
latch.await(); // 阻塞直到countDown到0
System.out.println("所有线程已完成");
 
 
2. CyclicBarrier
 
- 让一组线程等待至某个屏障点再一起执行:
 
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
    System.out.println("所有线程到达屏障,开始执行汇总任务");
});

// 3个线程各自执行任务,到达barrier时等待
for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        try {
            System.out.println(Thread.currentThread().getName() + " 准备到达屏障");
            barrier.await(); // 等待其他线程
            System.out.println(Thread.currentThread().getName() + " 继续执行");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }).start();
}
 
 
3. Semaphore
 
- 控制同时访问资源的线程数量(如限流):
 
Semaphore semaphore = new Semaphore(2); // 最多2个线程同时访问

for (int i = 0; i < 5; i++) {
    new Thread(() -> {
        try {
            semaphore.acquire(); // 获取许可,无许可时阻塞
            System.out.println(Thread.currentThread().getName() + " 获得许可,访问资源");
            Thread.sleep(1000); // 模拟访问资源
            System.out.println(Thread.currentThread().getName() + " 释放资源");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // 释放许可
        }
    }).start();
}
 
 
八、多线程开发最佳实践
 
1. 避免死锁:
- 按统一顺序获取锁,避免嵌套锁;使用 ReentrantLock 的 tryLock() 尝试获取锁并设置超时。
2. 优先使用线程池:避免手动创建大量线程,通过 ThreadPoolExecutor 自定义参数。
3. 减少同步范围:仅对共享资源加锁,避免同步整个方法。
4. 合理处理中断:通过 isInterrupted() 判断线程是否被中断,避免直接调用 stop() (已过时,可能导致资源未释放)。
5. 使用原子类替代同步:对简单操作(如计数)优先用 AtomicInteger 等原子类,提升性能。
 
总结
 
Java多线程通过 Thread 、 Runnable 等实现任务并行,结合 synchronized 、 ReentrantLock 解决线程安全问题,利用线程池和并发工具类提升开发效率。实际开发中需重点关注线程安全、性能优化和资源管理,避免死锁、竞态条件等问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值