Java基础 -- 多线程(一)
Java基础 -- 多线程(一)
1. 概念引入
-
什么是程序、进程、线程?
- 程序:静态源代码,指令集合
- 进程:程序的一次执行过程,资源分配和调度的基本单位
- 线程:轻量级进程,是进程的执行单元
-
并发与并行的区别?
- 并发:同一时刻,A和B同时发生
- 并行:同一时间间隔,宏观上A和B同时发生,微观上二者交替运行
-
为什么引入多线程?
- 切换线程比切换进程负担小,切换上下文开销小
- 提高程序的执行效率和运行速度
-
引入多线程可能存在的问题?
- 可能会引发线程安全,死锁等问题
【注】对于Java应用程序java.exe来说,最少存在三个线程:main()线程,gc()垃圾回收线程,异常处理线程;如果发生异常时,会影响主线程。
2. 创建启动线程
- 线程的创建方式有哪些?
创建线程共有四种方式:
-
继承Thread类(extends):继承类;重写run()方法;new Thread实例;start()启动线程
-
实现Runnable接口(implements):实现Runnable接口,重写run()方法;创建实现类的实例;实例作为参数传到Thread类构造器,创建Thread类的对象;start()启动线程
-
使用Callable,Future(implements):实现Callable接口;实现call() 方法;创建Callable接口实现类的对象;Callable实现类对象作为参数传到FutureTask构造器中,创建FutureTask对象;FutureTask对象作为参数传到Thread类构造器中,创建Thread对象;start()启动线程;获取Callable中call方法的返回值
-
线程池:提供指定数量的线程池(ExecutorService,ThreadPoolExecutor);执行指定的线程的操作;关闭线程池
-
start(),run()和call()是什么?为什么不能调用run()?
-
run(): 线程执行体,代表线程需要完成的任务
-
start(): 启动当前进程,调用当前进程的run() 方法
-
call(): 功能类似于run() ,有返回值,可抛出异常
-
若直接调用run()方法,就相当于调用一个普通方法,不会以多线程的方式执行
-
3. 线程声明周期
- 线程生命周期是怎样的?
4. 控制线程
- join() 是什么?
join():在线程a中调用线程b的join(),此时线程a进入阻塞状态,直到线程b完全执行之后,线程a才结束阻塞状态
总结:线程a中调用b.join(),代表线程a等线程b完成后结束阻塞
- 后台进程是什么?
后台进程,也叫守护进程,指的是后台运行,为其他线程提供服务;如果前台线程死亡,后台线程自动死亡
- sleep()是什么?
让线程暂停,进入阻塞状态
- yield() 是什么?
让线程暂停,进入就绪状态而非阻塞状态
- yield() 与 sleep() 区别?
-
线程优先级情况是怎样的?
-
线程默认优先级与父线程优先级相同
-
main() 线程普通优先级
-
静态常量
-
-
常见问题:sleep() 和 wait() 异同
-
相同点:二者都可以暂停线程执行
-
不同点:
-
sleep()没有释放锁;wait() 释放了锁
-
sleep() 用于暂停执行;wait() 用于线程通信
-
sleep()执行后,会自动苏醒;wait()执行后,需要调用notify()/notifyAll()唤醒,或者是wait(long timeout) 超时后线程会自动苏醒
-
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧