一、
1顺序执行流:
1-1单线程雇佣一个服务员的餐厅
1-2多线程雇佣多个服务员的餐厅
2任务、程序、进程:
3特征:
3-1独立性、动态性、并发性
3-2并发性、并行性
前者,某个时间点,只能执行一个程序。切换
后者,同时
4抢占式多任务操作策略
5进程初始化,主线程就被创建了。
6自己的堆栈,程序计数器和自己的局部变量。
7一个线程可以创建和撤销另一个线程
总结:
操作系统可以同时执行多个任务,每个任务就是进程;
进程可以同时执行多个任务,每个任务就是线程;
二、
1隔离度
低->线程并发性高
资源分配:多进程 分配独立的内存空间,分配大量的相关资源
多线程 简单 性能高
2线程共享环境:进程代码段、进程的共有数据
3多任务并发
三、创建和启动
每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码)。Java使用线程执行体来代表这段程序流。
1、线程执行体
主线程的线程执行体
2、线程命名
默认情况下:
主线程 main
用户启用的多个线程名:Thread-0、Thread-1....
3、实现Runnable,他的run方法仅作为线程执行体,实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run方法。
4、函数式接口。
区别:
1.直接创建的Thread子类即可代表线程对象;
2创建Runnable对象只能作为线程对象的target
四、使用Callable 和Future
1、包装成线程执行体。
2、
五、三种方式比较
六、生命周期
新建和就绪状态
当线程对象调用了start()方法之后,该线程处于就绪状态,Java虚拟机会为其创建方法调用栈和程序计数器,处于这个状态中的线程并没有开始运行,只是表示该线程可以运行力量。至于该线程何时开始运行,取决于JVM里线程调度器的调度。
注意:如果调用了线程的run方法后,该线程不处于新建状态,不要再次调用线程对象的start()方法了。
切换由底层平台控制,具有一定的随机性。
子线程立刻开始执行,则可以让主线程sleep1ms,因为CPU在这1ms中不会空闲,它会执行另一个处于就绪状态的线程。
时间段,剥夺。
线程调度器
系统线程调度
一三一五
join大问题划分为小问题
//系统还是时间线顺序执行。
2、后台线程:特征:如果所有前台线程都死亡,后台线程会自动死亡。
//主线程,JVM会主动退出。
前台线程创建的子线程默认是前台线程,后台线程创建的子线程默认是后台线程。
前台线程死亡后,JVM会通知后台线程死亡,但从它接收指令到做出响应,需要一定时间。
3、优先级
每个线程默认的优先级都与创建它的父线程的优先级相同,默认情况下,main线程具有普通优先级,由main线程创建的子线程也具有普通优先级。
七、同步
1、不具有同步安全性。
//比如,两人取款对同一账号取款,如果并发修改,取款,系统巧好在切换的时候,就会出错。
2、同步监视器。就是锁对象
!注意,任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程就会释放对该同步监视器的锁定。
//比如动车上上厕所。
条件:被并发访问的共享资源当同步监视器。
逻辑:加锁->修改->释放锁
这种方式可以保证并发线程在任一时刻只有一个线程可以进入修改稿共享资源的代码区(也被称为临界区),所以同一个时刻最多只有一个线程处于临界区内,保证了线程的安全性。
3、领域驱动设计,DDD,这种方式就是认为每个类都应该是完备的领域对象。
4、可变类和不可变类。
线程安全类
5、单线程环境和多线程环境
前者:StringBuider:保证较好的性能
后者:StringBuffer:保证多线程安全