
多线程
发布日期:2021-05-10 03:44:19
浏览次数:25
分类:精选文章
本文共 3521 字,大约阅读时间需要 11 分钟。
Java多线程编程详解
1. 进程与线程
在计算机科学中,进程和线程是并发编程的基础概念。一个进程可以看作是一个执行应用程序的实例,它拥有一定的内存空间和系统资源。线程则是在进程中由操作系统调度和分派的基本单位,负责执行应用程序的具体任务。线程是CPU调度的基本单位,负责完成特定的顺序控制流程。
线程的特点
- 独立执行:线程是进程中的最小执行单位,能够独立执行任务。
- 资源共享:线程共享进程的内存和系统资源。
- 并发执行:线程之间可以交替执行,提高资源利用率。
进程与线程的区别
- 资源占用:进程占用更多的系统资源,包括内存、文件描述符等。
- 启动方式:进程通常由操作系统启动,而线程可以在进程内部动态创建。
- 调度粒度:进程的调度粒度较大,线程的调度粒度较小。
2. 多线程编程
多线程的优势
- 资源利用:充分利用CPU资源,减少等待时间。
- 任务并行:实现多任务同时执行,提升效率。
- 用户体验:减少用户等待时间,提升应用响应速度。
多线程的实现方式
- 继承Thread类:通过继承Thread类,重写run方法实现线程。
- 实现Runnable接口:通过实现Runnable接口,使用Thread类执行Runnable实例。
Thread类与线程管理
- 主线程:main方法即为主线程,负责程序的入口。
- 子线程:通过start方法启动其他线程。
- 线程状态:线程可以处于新建、就绪、运行、阻塞、等待、终止状态。
3. 线程创建方式对比
继承Thread类
- 代码示例:
public class MyThread extends Thread { public void run() { for (int i = 1; i <= 10; i++) { System.out.println(Thread.currentThread().getName() + "第" + i + "次执行"); } } public static void main(String[] args) { MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.start(); t2.start(); }}
优点:直接操作线程,适用于单继承。
实现Runnable接口
- 代码示例:
public class MyRunnable implements Runnable { public void run() { for (int i = 1; i <= 10; i++) { System.out.println(Thread.currentThread().getName() + "第" + i + "次执行"); } } public static void main(String[] args) { Runnable myRunnable = new MyRunnable(); Thread t1 = new Thread(myRunnable, "线程1"); Thread t2 = new Thread(myRunnable, "线程2"); t1.start(); t2.start(); }}
优点:避免单继承的局限性,适合多继承场景。
4. 线程的状态与调度
线程状态
线程在执行过程中会经历多个状态:
- 新建状态:线程创建时的初始状态。
- 就绪状态:线程准备好执行的状态。
- 运行状态:线程正在CPU上执行任务的状态。
- 阻塞状态:线程等待I/O操作完成的状态。
- 等待状态:线程等待其他线程通知的状态。
- 终止状态:线程正常结束的状态。
线程调度
线程调度是操作系统将线程分配CPU的过程。使用Thread类中的方法可以对线程进行调度:
start()
:启动线程执行。join()
:等待线程完成。wait()
:让线程等待。notify()
:唤醒等待的线程。yield()
:让当前线程暂停,供其他线程执行。
线程优先级
线程优先级由1到10表示,1为最低优先级,10为最高优先级。优先级高的线程获得CPU资源的概率较大。
5. 线程的同步与锁
同步代码块
synchronized代码块可以保护共享资源的访问,防止数据竞争和 race condition。使用synchronized块可以确保在多线程环境下,共享资源的访问是安全的。
死锁
死锁是指多个线程在等待对方完成的操作而无法继续执行的状态。发生死锁的原因是线程尝试占有多个锁,而这些锁之间没有相互释放的机制。
解决死锁
- 减少锁嵌套:尽量减少对多个锁的嵌套使用。
- 释放锁:确保当前线程在等待时释放锁。
- 使用非阻塞锁:如ReentrantLock,提供更高的灵活性。
6. 生产者与消费者问题
问题描述
生产者不断生产商品,消费者不断消费商品。如何在高并发环境下确保生产者和消费者的高效交替,防止数据丢失和不一致。
解决方案
- 使用synchronized方法控制对共享资源的访问。
- 使用wait和notify方法实现生产者与消费者的等待和通知。
- 使用ThreadLocal来保护共享资源的局部性。
代码示例
public class Movie { private String name; private String info; private Boolean flag = true; public String getName() { return name; } public String getInfo() { return info; } public synchronized void get() { if (flag) { try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(this.getName() + "-" + this.getInfo()); flag = true; super.notify(); } public synchronized void set(String name, String info) { if (!flag) { try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info = info; flag = false; super.notify(); }}
7. 实际应用中的线程优化
线程礼让
线程礼让可以让当前线程暂停一段时间,允许其他线程获得执行机会。
线程强制执行
在某些场景下,需要强制让线程立即执行当前任务,而不等待I/O操作完成。
线程阻止与恢复
使用Thread类的stop和resume方法,可以对线程进行阻止和恢复操作。
8. 总结
多线程编程能够显著提升应用程序的性能,但也带来了较高的复杂性。合理使用线程池、同步机制和并发控制,可以有效避免线程安全问题,提升应用程序的稳定性和性能。
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2025年04月09日 14时35分08秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Java多线程
2019-03-07
openssl服务器证书操作
2019-03-07
我用wxPython搭建GUI量化系统之最小架构的运行
2019-03-07
我用wxPython搭建GUI量化系统之多只股票走势对比界面
2019-03-07
selenium+python之切换窗口
2019-03-07
重载和重写的区别:
2019-03-07
搭建Vue项目步骤
2019-03-07
账号转账演示事务
2019-03-07
idea创建工程时错误提醒的是architectCatalog=internal
2019-03-07
SpringBoot找不到@EnableRety注解
2019-03-07
简易计算器案例
2019-03-07
在Vue中使用样式——使用内联样式
2019-03-07
Explore Optimization
2019-03-07
解决数据库报ORA-02289:序列不存在错误
2019-03-07
map[]和map.at()取值之间的区别
2019-03-08
成功解决升级virtualenv报错问题
2019-03-08
【SQLI-Lab】靶场搭建
2019-03-08
【Bootstrap5】精细学习记录
2019-03-08