# zb_java00807 **Repository Path**: climpeaker/zb_java00807 ## Basic Information - **Project Name**: zb_java00807 - **Description**: 多线程 - **Primary Language**: Java - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2018-08-07 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # zb_java00807 # 课堂笔记 *多线程* *线程同步* ## 1 多线程 ### 1.1 多进程 * 1 进程概念 进程:进程是操作系统资源分配和调度的基本单位;【扩展:进程调度算法】 程序=代码+数据结构; 进程是动态的程序,也就是程序在操作系统中运行的状态; 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。 进程三种基本状态: (1)就绪态(Ready) 除cpu之外的所有的资源都就绪,此时就是进程的就绪态; (2)运行态(Running) 独占cpu资源,在cpu运行就是运行态; (3)阻塞态(Blocked) 因为IO等中断以及cpu时间片到时,放弃cpu资源而等待终中断事件的完成的状态就是阻塞态; 此外还有: (4)创建 刚刚创建了一个进程; (5)结束 进程执行完成结束,释放资源; 注意: 进程有5态图和7态图; 7态图涉及到了外部缓存(二级缓存)的调度算法;【扩展】 * 2 线程概念 线程是进程的一个更小的分割;也叫作微进程; 线程不能独立占有资源,线程存在于进程中,同一个进程中的多个线程可以共享资源; 线程也有5态图和7态图; 进程和线程都有调度算法【扩展】 多个线程之间可以并发执行; 并发:在一个时间段内多个线程交替执行的状态; 注意:是在一个时间段内,不是时间点; 因为线程可以并发执行,会产生死锁; 【扩展】 死锁:线程的死锁是并发执行的多个线程之间相互占有彼此需要的关键资源,都等待对方去释放关键资源而造成相互等待,就是死锁; 死锁产生有四个条件: (1) 互斥条件 (2) 请求和保持条件 (3) 不可抢占条件 (4) 循环等待条件 死锁解决方法: 打破上面四个条件中一个即可; 典型案例【哲学家进餐问题】 * 2 线程编程 *(1)多线程编程* (1)继承Thread类实现; (2)继承Runnable接口; 注意: (1)两种实现方式都是通过重写run方法,来完成线程的业务逻辑处理; (2)线程对象必须通过调用start方法来进行启动一个线程, 然后jvm会自动调用run方法执行线程;【如果直接调用run方法结果会如何?】 (3)线程终止,run方法执行完成线程自动终止;或者是exit退出系统也会结束一个线程; (4)Thread类中常用的方法; join方法: 在一个主线程中调用另外一个子线程,主线程会等待子线程执行结束之后,才继续执行;【教材150】 yield方法: 终止当前线程,放弃cpu资源让其他线程去执行;【考虑优先级,只有优先级>=当前线程的其他线程才有资格抢占cpu资源】 转入就绪态; sleep方法: 终止当前线程,放弃cpu资源让其他线程去执行;【不考虑优先级,任何线程都可以抢占cpu资源】 转入阻塞态; 【sleep方法和yield方法的异同点:教材】 interrupt方法: 中断线程的阻塞状态;打断线程的sleep方法,会引发InterruptException;线程不再进入运行状态;【p148】 (5)线程分类:用户线程和守护线程 用户线程:与业务处理相关;是用户级别的; 守护线程:与系统运行相关;是系统级别的;【为用户线程提供基础服务的线程】 (6)线程的优先级从1到10;默认是5;有对应的常量; 课下作业: (1)wait和sleep的异同点; *(2)多线程终止* 因为多线程的stop方法是一个过时的方法; 一般可以通过设置一个标识变量或者是调用一个方法接口来终止run方法进而结束一个多线程; * 2 线程同步 *多线程同步概念* 多线程是并发执行的,当多个线程访问某一个关键资源时,可能会产生一种交叉访问的现象,造成数据访问不一致。【脏数据】 为了保证并发的多线程可以有序访问关键资源,可使用加锁机制保证多个线程有序访问该资源; 加锁机制: 当线程获取了某个关键资源之后,会给该资源加一个同步锁,在该线程操作该资源结束之前其他线程不能在访问该资源,而是等当前线程释放了该资源以后再进行访问。这样就避免了多个线程交替操作该资源的问题【脏数据】。 *synchronized关键字* 第一种应用: 语法: synchronized(被加锁对象){ 对被加锁对象的操作; } 解析: (1)synchronized关键字加锁的对象类型只能是对象类型,如果是基本类型,则需要使用与之对应的包装类类型【包装类类型的存在价值】 第二种应用: 语法: 修饰方法; 注意: (1)使用synchronized关键字会系统开销,需要保证线程同步,所以单线程中不要使用他; (2)synchronized关键字加锁的对象范围越小,系统开销越少,所以,尽可能将加锁范围缩小; 【课下作业】 比较synchronized和lock异同点; * 3 多线程综合应用——生产者与消费者问题 业务描述: (1)有一个生产者,负责生产产品,将产品放入仓库; (2)有一个消费者,负责消费产品,从仓库消费产品; (3)采用多线程的机制,保证生产行为和消费行为能够有序进行; 业务分析: (1)仓库是一个关键资源,生产者和消费者只能互斥访问; (2)生产者生产的产品堆满仓库以后,应该停止生产,等待消费者消费产品,当仓库有空余时再次进行生产; (3)消费者亦同; (4)仓库可以采用栈的方式实现; 注意: 多线程的wait和notify通信机制,需要在synchronized进制下才使用; #### 参与贡献 1. Fork 本项目 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [http://git.mydoc.io/](http://git.mydoc.io/) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)