多线程
并发、并行
线程、进程
线程调度
![](https://i-blog.csdnimg.cn/blog_migrate/f8742e7b84044739950add8e4d10933a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e4f0159d53fe3fd3d15bac2f29a62363.png)
创建线程类
单线程弊端:一个线程出现异常,后面程序不执行
创建多线程的方法一(相比Runnable有缺陷)(继承Thread不适合资源共享)
(创建Thread子类、重写run方法、创建Thread任务、调用start方法)
子类继承Thread,重写方法run(),其中添加线程任务
测试类主方法中创建该子类对象,调用start()方法,新设置一个线程任务for()
多线程原理——随机打印结果
多线程内存图
Thread类常用方法
getName ( ) 取线程名称
1、Thread中getName()获取线程名,2、Thread中currentThread() 返回当前线程对象
1、getName() 2、currentThread()
setName ( ) 设置线程名称
1、Thread中setName()设置线程名
2、创建子类有参构造,其中调用父类有参构造,将线程名传给父类,创建线程对象时,让父类有参构造给线程起名
1、setName 2、创建对象,构造方法设置名称
sleep ( ) 设置当前线程按指定毫秒暂停
创建多线程方法二(主要使用的方法)
(Runnable接口实现类,重写run,实现类对象,Thread对象,start方法)
![](https://i-blog.csdnimg.cn/blog_migrate/e0789934876b306ab70bcc28e81c6590.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5950d52c634ef099566c90dfa575a2b6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c72d876b5ad8dc5da3914425ee089264.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5916fc8b06c9ba5b54b72f4297ce626d.png)
使用Runnable,设置线程任务 和 开启线程 分离
用谁传谁,传递不同实现类,实现不同的任务
匿名内部类实现线程创建(Runnable的父类和接口方法)
匿名内部类的父类实现
匿名内部类的接口实现
简化接口方法
Thread和Runnable区别
https://blog.csdn.net/weixin_38004638/article/details/88948979
Runnable比Thread更有优势
一、Runnable、Thread比较
首先阐述实现Runnable的好处:
java不允许多继承,因此实现了Runnable接口的类可以再继承其他类。
至于两者的真正区别最主要的就是一个是继承,一个是实现;其他还有一些面向对象的思想,Runnable就相当于一个作业,而Thread才是真正的处理线程,我们需要的只是定义这个作业,然后将作业交给线程去处理,这样就达到了松耦合,也符合面向对象里面组合的使用,另外也节省了函数开销,继承Thread的同时,不仅拥有了作业的方法run(),还继承了其他所有的方法。综合来看,用Runnable比Thread好的多。
线程安全问题
try...catch放在if语句里面,保证每个线程都先判断后再睡眠
总结:多个线程同时处理一个任务,会发生同时开启,或无法同时停止的线程安全问题
线程同步
1、同步代码块;2、同步方法;3、锁机制
1、同步代码块
@ 同步代码块中的锁对象,可以是任意对象
@ 但是必须保证多个线程使用的是同一个锁对象
@ 锁对象的作用:
把同步代码块锁住,只让一个线程在同步代码块中执行
1、在Runnable接口实现类中创建--锁对象//在实现类中创建object对象,作为锁对象
2、在接口实现类的 run ( )方法中,使用 sychronized ( ) 方法传入锁对象,放入访问共享数据的代码 //访问共享数据的代码放入synchronized,锁对象做参数
2、同步方法(不需要单独创建锁对象)(锁对象是接口实现类对象)
1、创建同步方法
![](https://i-blog.csdnimg.cn/blog_migrate/490be82619076fa0f4282308b58af369.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2c6724094cff0d709384a842e71beebb.png)
2、实现类中run ( )方法调用该同步方法
![](https://i-blog.csdnimg.cn/blog_migrate/fd768e289df90521bd5f7d0e38126990.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8c227c3ba9d2cba657718c84d9d2eb01.png)
同步方法的锁对象
//注释掉synchronized关键字,增加synchronized ( ),this就是调用该方法的类
静态同步方法(优先于对象)
静态同步方法的锁对象--------本类的class属性------>class文件对象
调用该方法的对象是相同的,那么锁必然相同,否则就不相同。
3、Lock锁
线程状态
新建状态 NEW 至今尚未启动的线程处于这种状态。还未调用start()启动
运行状态 RUNNABLE 正在Java 虚拟机中执行的线程处于这种状态。
调用start ( ),进入运行状态
阻塞状态 BLOCKED 受阻塞并等待某个监视器锁的线程处于这种状态。
cpu不空闲,则会进入阻塞状态
无限等待 WALLING 无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。
当运行中线程调用 object.wait ( ),未传参数,线程进入无限等待状态
调用 object.notify ( ), 唤醒线程
休眠状态 TIMED_WALLING 等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。
sleep ( long ),或 wait ( long ),进入休眠状态,休眠结束,判断cpu可用否
死亡状态 TERMINATED 已退出的线程处于这种状态。
当Run ( ) 结束,或stop ( ) , 进入死亡状态
操作系统进程状态转换图
wait(): 进入无限等待 notify()唤醒在此对象监视器上等待的单个线程
wait(long)/ sleep(long):在指定的毫秒数内睡眠
TIMED_WAITING
![](https://i-blog.csdnimg.cn/blog_migrate/faf7451648d5aab91cf90914ba28886f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9557ba57463c69db7239ffc841205a75.png)
![](https://i-blog.csdnimg.cn/blog_migrate/359284d84db789ee7fd09af55163b813.png)
![](https://i-blog.csdnimg.cn/blog_migrate/682a532c53a40f148ac93bda47666832.png)
![](https://i-blog.csdnimg.cn/blog_migrate/22b01a9df65ff8008f066164daf39b7c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/561da21809625e3ea7e45c9d433676d9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f1a0b63e9e026bd8789784342c414e1e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e6a0713d40e504b265b8c8c1d638c69d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ac0c0c27d068fa0f9b8cbaa917a42c91.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ab69c90113b5bf4ef3132d6444addd88.png)
![](https://i-blog.csdnimg.cn/blog_migrate/342f9588d78fadd6044d26417a58d54d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5760fab438d73c9a932b45d396cd1e8c.png)
WAITING等待唤醒
创建锁对象obj,再创建两个Thread对象,调用start启动多线程,Thread对象使用匿名内部类
顾客对象重写的run()方法中,同步代码块中,调用锁对象obj的wait()方法无限等待(直到做好包子),返还锁对象
老板对象重写的run()方法中,在同步代码块前,调用Thread的sleep(5000)做事,之后同步代码块,传入锁对象,调用notify唤醒
Object类中wait(Long)带参方法和notifyAll