多线程
进程和线程这块去看os这块的进程知识#
这本书很好
继承Thread类#
实现多线程的时候,要注意
- 需要继承Thread类
- 必须重写run方法,核心执行的逻辑
- 线程在启动的时候不要直接调用run方法,而是要通过start()方法来进行调用
public class ThreadDemo extends Thread{ public void run(){ for(int i = 0; i < 10; i++){ // coding } } public static void main(String[] args){ ThreadDemo ThreadDemo = new ThreadDemo(); ThreadDemo.start(); for(int i = 0; i < 5; i++){ // coding } } }
如果像下面这么写,只会运行main这个线程
public class ThreadDemo extends Thread{ public void run(){ for(int i = 0; i < 10; i++){ // coding } } public static void main(String[] args){ ThreadDemo ThreadDemo = new ThreadDemo(); ThreadDemo.run(); for(int i = 0; i < 5; i++){ // coding } } }
实现Runnble接口(推荐使用,因为java单继承,将继承关系留给最需要的类;方便共享资源)#
使用了代理设计模式#
- 实现了runnable方法
- 重写run方法
- 创建Thread类,将刚刚创建好得到runnbale的自类实现作为thread类的构造参数
- 通过Thread.start()进行启动
- 使用runnable接口之后不需要给共享变量添加static关键字,每次创建一个对象
public class TicketRunnable implements Runnable{ private int ticket = 5; public void run(){ for(int i = 0; i < 100; i++){ if(ticket > 0){ // coding } } } public static void main(String[] args){ TicketRunnable ticket = new TicketRunnable(); TicketThread t1 = new Tread(ticket); TicketThread t2 = new Tread(ticket); TicketThread t3 = new Tread(ticket); TicketThread t4 = new Tread(ticket); t1.start(); t2.start(); t3.start(); t4.start(); } }
线程声明周期#
- 新生状态,创建好当前线程对象之后,没有启动之前(调用start方法前)
- 就绪状态,准备开始执行,并没有执行,表示调用start方法之后
- 运行状态,当前进程获取CPU资源后,就绪对立中的线程抢占CPU
- 死亡状态,运行中线程正常执行完所有代码逻辑,因为异常情况导致程序结束
- 阻塞状态,发生某些异常情况,导致当前线程无法顺利执行下去,紧入阻塞状态,阻塞结束后进入就绪状态
五状态模型#
如何进入死亡状态#
- 正常结束
- 人为中断执行,stop方法
- 程序抛出未捕获的异常
如何进入阻塞状态#
- sleep方法
- 等待io资源
暂停/停止线程的方法#
- sleep,当前线程处于阻塞状态
- yield,暂停正在进行的线程,允许其他线程进行,不阻塞,如果没有其他执行的线程,当前线程会立马执行
- join,当某个线程等待另一个线程执行结束后,才继续执行,调用该方法的线程在此前执行完毕,等待调用该方法的线程执行完毕后执行
- stop,强制结束线程,暴力结束
同步#
- 每次启动线程对象的时候都会创建自己对象的属性值,没有真正实现共享
- 将共享对象,共享变量设置成static
- 每次访问共享对象时,数据不一致
- 此时使用线程同步,即加锁
同步的前提#
- 必须有两个或两个以上的线程
- 必须是多个线程使用同一资源
- 必须保证同步中只能有一个线程运行
CAS 无锁式同步机制#
同步代码块synchronized(共享资源,共享对象,需要Object的子类)
public class SleepTest implements Runnable{ private int ticket = 5; public void run(){ for(int i = 0; i < 100; i++){ try{ Thread.sleep(200); }catch(Exception e){ e.printStackTrace(); } synchronized(this){ if(ticket > 0){ // coding } } } } public static void main(String[] args){ TicketRunnable ticket = new TicketRunnable(); TicketThread t1 = new Tread(ticket, "A"); TicketThread t2 = new Tread(ticket, "B"); TicketThread t3 = new Tread(ticket, "C"); TicketThread t4 = new Tread(ticket, "D"); t1.start(); t2.start(); t3.start(); t4.start(); } }
synchronized,同步方法,不需要指定共享对象
public class SleepTest implements Runnable{ private int ticket = 5; public void run(){ for(int i = 0; i < 100; i++){ this.sale(); } } public void synchronized sale(){ try{ Thread.sleep(200); }catch(Exception e){ e.printStackTrace(); } if(ticket > 0){ // coding } } public static void main(String[] args){ TicketRunnable ticket = new TicketRunnable(); TicketThread t1 = new Tread(ticket, "A"); TicketThread t2 = new Tread(ticket, "B"); TicketThread t3 = new Tread(ticket, "C"); TicketThread t4 = new Tread(ticket, "D"); t1.start(); t2.start(); t3.start(); t4.start(); } }
同步监视器#
synchronized(obj){}中的obj称为同步监视器
生产者-消费者#
get和set加同步锁
加信号量同步
wait(),进入阻塞状态,notify,进入唤醒状态
JUC,Java Util Concurrent#
1.5以后出的新功能
作者:BigBender
出处:https://www.cnblogs.com/BigBender/p/14213493.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2019-12-30 B1012. 数字分类
2019-12-30 B1008. 数据元素循环右移问题
2019-12-30 函数的概念
2019-12-30 编译原理--引论(四)
2019-12-30 编译原理--引论(三)
2019-12-30 2012年英语一小作文
2019-12-30 函数连续性