18、Java——多线程
多线程:
三高: 高可用 高性能 高并发
1、thread 类
(1)线程是程序中执行的线程。Java虚拟机允许应用程序同时运行多个执行线程。多线程:多任务执行,多条路径可以执行,多线程的优点:提高效率
①进程 与 线程 之间的区别:
a进程: 系统中的应用程序,一个进程之间包含1~n个线程,进程具有自己的资源,内存空间,进程是资源分配的最小单位
b.线程: 一个程序中的顺序流,多个线程共享一个进程的资源和数据空间,每一个线程具有自己的程序计数器,线程是cpu调度的最小单位
②学习的目标:
a.线程的创建于开启
b.线程的状态 : 新生 就绪 运行 阻塞 终止
c.线程安全
d.线程通信 wait() notify()
③线程的创建:
a.继承Thread,重写run()方法,定义线程体 + start()
b.实现Runnable接口,重写run()方法 + start() --> 推荐
(2)实现Runnable接口,重写run方法 + start()
①类是单继承,接口多实现
②可以实现资源共享
张票 3个人买完
共享的资源: 100张张票
多线程: 4个线程 1个主线程 3个线程买票
注意: 多线程同时操作同一份资源就有可能出现线程不安全问题
(3)模拟12306购票
100张票 3个人买完
共享的资源: 100张张票
多线程: 4个线程 1个主线程 3个线程买票
(5)注意:
(6)实现Callable,重写call(),在方法内部定义线程体 --> 了解
②可以定义返回值
2、线程的状态:
(1)新生状态 : new Thread(),当前线程处于新生状态
②就绪状态 : start(),这个线程进入就绪状态,线程准备好可以被cpun
③运行状态 : 当cpu调度到这个线程,线程进入到运行状态开始执行
④阻塞状态 : 当程序无法正常执行(进入阻塞状态的多种方式...)
⑤终止状态 : 线程结束
a.一个线程一旦终止,无法恢复
b.一个线程如果进入阻塞状态,阻塞接触会直接恢复到就绪状态
⑥进入到阻塞状态的几种方式 :
a.sleep(),b.join(),c.wait(),d.IO
⑦进入线程就绪状态的方式:
a.start(),b. yield(),c.线程切换,d.阻塞接触
⑧进入终止状态的方式:
a..stop 已经过时,不推荐使用,b.正常之间完毕,c.添加标识判断 --> 推荐
⑨sleep(ms) : 1s = 1000ms
a.线程休眠|睡眠b.会进入到阻塞状态,当指定的ms数结束,线程会恢复到就绪状态c.抱着资源睡觉d.让出cpu的资源e.抱着是指对象的资源|锁
⑩作用 :a.模拟网络延迟,b.方法问题的可能性
(2)yield 礼让线程 高风亮节
当一个线程调用yield,让出cpu的资源,进入到就绪状态,静态方法
(3)join() 插队线程
①join(ms) 插队指定的ms数,成员方法join,线程对象.join() 当前线程对象插队
(4)void interrupt() 为线程添加一个中断标识
①boolean isInterrupted() 测试此线程是否已被中断,是否已经调用过 interrupt()方法添加中断标识,是->true 不是->false
②static boolean interrupted() 测试当前线程是否已被中断, 是否已经调用过 interrupt()方法添加中断标识,是->true 不是->false,同时会复位标识
④sleep--> InterruptedException - 如果有任何线程中断了当前线程。 抛出此异常时,将清除当前线程的中断状态 。
(5)getState() 获取当前线程的状态
Thread.State 线程状态。 线程可以处于以下状态之一:
①NEW,尚未启动的线程处于此状态。
②RUNNABLE,在Java虚拟机中执行的线程处于此状态。
③BLOCKED,被阻塞等待监视器锁定的线程处于此状态。多线程操作下,处于等待对象锁的线程处于这种状态
④WAITING,无限期等待另一个线程执行特定操作的线程处于此状态。 wait(),join()
⑤TIMED_WAITING,正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态。阻塞与时间相关的线程处于这种状态 sleep(ms),join(ms),wait(ms)
(6)Priority 线程的优先级
①线程的优先级越高,有限执行的可能性越大
a.1~10 线程优先级的数值范围
b.默认5 NORM_PRIORITY
c.最小1 MIN_PRIORITY
d.最大10 MAX_PRIORITY
②setPriority(int) 设置一个线程的优先级,getPriority() 获取一个线程的优先级
(7)线程:
①用户线程,守护线程
②守护线程就是用来守护用户线程,当程序中所有的用户线程全部执行完毕,守护线程会直接结束
③setDaeson(true) 设置守护线程
④isDaeson() 判断线程是否为守护线程
⑤现在所创建的线程默认都是用户线程
⑥垃圾回收机制典型的守护线程
3、线程安全问题:
多线程同时操作同一份资源才有可能遇到线程不安全问题
(1)同步锁: 让关键重点代码排队执行,其他代码依旧同时执行,在提高效率的基础上保证数据安全
(2)synchronized 关键字
①关注点:
a.限制条件: 对象锁(每一个对象只有一把锁) 锁哪一个对象能锁住
b.同步的代码范围: 范围太大,效率低,范围太小,容易锁不住
②使用方式:
a.同步方法 b.静态方法 c.排队执行的代码范围: 方法体 d.锁的对象 : 锁类
③成员方法 :a.排队执行的代码范围: 方法体
b.锁的对象 : 调用成员方法的对象
c.同步块
synchronized(锁的对象){
排队执行的代码;
}
锁的对象 : this 类:类的Class对象 资源
④同步方法特点:
(2)同步块
①synchronized(对象){
同步代码段;
}
()-->
This,类,资源
②注意:
a.同步成员方法,相当于同步调用成员方法的对象,相当于同步this
b.成员方法中this指代调用成员方法的对象
c.锁对象相当于锁住了这个对象的所有资源|成员,如果只想要锁住某个资源,可以单独只锁资源
(3)同步块
①synchronized(对象){
同步代码段;
}
()-->
This,类,资源
②注意:
a.锁不变的内容
b.自定义引用数据类型对象地址不变
(4)同步块
①synchronized(对象){
同步代码段;
}
()-->
②类 : 类的Class对象,获取类型的Class对象-->类名.class
③注意:锁类相当于锁了这个类的所有对象,如果只想要锁当前类得到某一个对象,可以直接去锁对象,用哪个锁哪个