当前位置: 首页 > news >正文

编程自学指南:java程序设计开发,多线程编程,为什么需要多线程?线程的创建与启动,线程同步与锁机制,线程池

编程自学指南:java程序设计开发,多线程编程

学习目标

  1. 理解进程与线程的核心概念及区别

  2. 掌握Java中线程的创建与生命周期管理

  3. 能够通过同步机制解决线程安全问题

  4. 使用线程池优化多线程程序性能


一、课程引入

1.1 为什么需要多线程?

  • 应用场景

    • 提高程序响应速度(如GUI界面后台任务)

    • 充分利用多核CPU资源

    • 实现异步处理(如文件下载、网络请求)

  • 生活类比

    • 进程:银行营业厅(独立资源单位)

    • 线程:银行窗口(共享进程资源,并发处理任务)


二、线程的创建与启动

2.1 继承Thread类

案例1:简单线程执行
public class MyThread extends Thread {  
    @Override  
    public void run() {  
        System.out.println("线程执行:" + Thread.currentThread().getName());  
    }  
}  

// 启动线程  
MyThread thread = new MyThread();  
thread.start();  // 输出:线程执行:Thread-0

2.2 实现Runnable接口(推荐)

案例2:多窗口售票系统
public class Ticket implements Runnable {  
    private int tickets = 10;  

    @Override  
    public void run() {  
        while (tickets > 0) {  
            System.out.println(Thread.currentThread().getName() + "售出票号:" + tickets--);  
        }  
    }  
}  

// 启动三个窗口  
Thread t1 = new Thread(new Ticket(), "窗口1");  
Thread t2 = new Thread(new Ticket(), "窗口2");  
t1.start();  
t2.start();  
// 注意:此处存在线程安全问题(后续解决)


三、线程同步与锁机制

3.1 synchronized关键字

案例3:解决售票超卖问题
public class SafeTicket implements Runnable {  
    private int tickets = 10;  

    @Override  
    public void run() {  
        while (true) {  
            synchronized (this) {  // 同步代码块  
                if (tickets > 0) {  
                    System.out.println(Thread.currentThread().getName() + "售出票号:" + tickets--);  
                } else {  
                    break;  
                }  
            }  
        }  
    }  
}

3.2 Lock接口(ReentrantLock)

案例4:使用Lock实现同步
private Lock lock = new ReentrantLock();  

public void run() {  
    while (true) {  
        lock.lock();  
        try {  
            if (tickets > 0) {  
                System.out.println(Thread.currentThread().getName() + "售出票号:" + tickets--);  
            } else {  
                break;  
            }  
        } finally {  
            lock.unlock();  
        }  
    }  
}

3.3 volatile关键字

  • 作用:确保变量可见性,禁止指令重排序

private volatile boolean running = true;  

public void run() {  
    while (running) {  
        // 执行任务  
    }  
}  

public void stop() {  
    running = false;  
}


四、线程池

4.1 Executor框架

案例5:使用线程池执行任务

ExecutorService pool = Executors.newFixedThreadPool(3);  
for (int i = 0; i < 10; i++) {  
    pool.execute(() -> {  
        System.out.println(Thread.currentThread().getName() + "执行任务");  
    });  
}  
pool.shutdown();

4.2 Callable与Future

案例6:获取异步计算结果

Callable<Integer> task = () -> {  
    Thread.sleep(1000);  
    return 1 + 1;  
};  

ExecutorService pool = Executors.newSingleThreadExecutor();  
Future<Integer> future = pool.submit(task);  
System.out.println("计算结果:" + future.get());  // 阻塞直到结果返回  
pool.shutdown(); 

五、综合应用

5.1 案例7:生产者-消费者模型

public class MessageQueue {  
    private Queue<String> queue = new LinkedList<>();  
    private int capacity = 5;  

    public synchronized void produce(String msg) throws InterruptedException {  
        while (queue.size() == capacity) {  
            wait();  // 队列满时等待  
        }  
        queue.offer(msg);  
        notifyAll();  // 唤醒消费者  
    }  

    public synchronized String consume() throws InterruptedException {  
        while (queue.isEmpty()) {  
            wait();  // 队列空时等待  
        }  
        String msg = queue.poll();  
        notifyAll();  // 唤醒生产者  
        return msg;  
    }  
}

六、常见问题与最佳实践

6.1 常见错误

  • 错误1:直接调用run()方法

    thread.run();  // 错误:不会启动新线程,仍在主线程执行
  • 错误2:锁对象选择不当

    synchronized (new Object()) { ... }  // 锁无效!

6.2 最佳实践

  • 优先实现Runnable接口:避免单继承限制

  • 使用线程池代替手动创建线程:资源可控,避免频繁创建销毁开销

  • 避免死锁:按固定顺序获取多个锁


七、总结与练习

7.1 总结

  • 线程创建:继承Thread vs 实现Runnable/Callable

  • 线程同步:synchronized、Lock、volatile

  • 线程池:Executor框架管理线程生命周期

7.2 课后任务

  1. 实现一个多线程下载器(模拟分块下载文件)

  2. 用线程池优化案例2的售票系统

  3. 预习下一节课:网络编程基础

7.3 扩展挑战

  • CompletableFuture实现异步任务链(如先查询用户信息,再查询订单)

相关文章:

  • HarmonyOS NEXT - 电商App实例三( 网络请求axios)
  • blender使用初体验(甜甜圈教程)
  • 软件/硬件I2C读写MPU6050
  • 嵌入式八股ARM篇
  • ubuntu-学习笔记-nextjs部署相关
  • 嵌入式硬件: GPIO与二极管基础知识详解
  • WebSocket生命周期和vue中使用
  • C++中的单例模式及具体应用示例
  • centos Supported Java versions are: [17, 21]
  • VLAN,DHCP实验访问物理机
  • Docker 构建 nginx-redis-alpine 项目详解
  • Java高级-04.反射-获取成员变量和方法对象并使用
  • Docker 》》Docker Compose 》》network 网络 compose
  • 想成为网络安全技术爱好者(可能是黑客)的话,需要看什么书?
  • 交易系统【三】网关
  • opencv 图片颜色+轮廓识别
  • SSM企业台账管理平台
  • Vue3全局化配置(ConfigProvider)
  • LabVIEW旋转设备状态在线监测系统
  • 多元时间序列预测的范式革命:从数据异质性到基准重构
  • 国台办:实现祖国完全统一是大势所趋、大义所在、民心所向
  • 广东早熟荔枝“抢滩”上海,向长三角消费者喊话:包甜,管够
  • 俄乌拟在土耳其举行会谈,特朗普:我可能飞过去
  • 英媒:英国首相住所起火,目前无人伤亡
  • 从“求生”到“生活”:医保纳入创新药让梗阻性肥厚型心肌病患者重拾生活掌控权
  • 媒体和打拐志愿者暗访长沙一地下代孕实验室,警方已控制涉案人员