二、线程同步[线程安全]
1.产生的原因:
--多个线程共享一个资源
2.解决的办法:
--添加同步锁 synchronized
(1)同步方法锁:
a.只能同时被一个线程所持有,当线程执行完这个方法的时候,才会将锁释放
b.锁范围越大,效率越低
c.锁在方法上,实际上锁的还是this对象上加锁
d.锁普通方法: this对象上加锁
锁静态方法: 锁 类.class(类的字节码文件)对象
(2)同步代码块:
a.可以将一部分代码加锁, 同步代码锁,需要借助一个对象
b.加锁的对象: 可以是任意对象,只需要确保是多个线程所共享(对象是唯一的)
c.一般来说都会使用this表示对象
d.同步锁(对象锁),一个对象只能加一把锁,并且只能同时被一个线程所持有的
线程同步锁 --synchronized
使用锁的原则:尽量将少量代码上锁
同步代码块:可以给一部分代码上锁,需要借助一个对象
加锁的对象:可以是任意对象,只要确保多个线程所共享
同步方法锁:
a.锁在方法上,实际上锁的是对象(this)
3.Lock锁 - 接口
1).实现类 -> ReentreantLock(可重入锁)
2).API:
加锁: 锁对象.lock()
解锁: 锁对象.unlock()
3)乐观锁/悲观锁 -> 理解原理(使用场景)
线程状态:
新建状态: new 一个对象
就绪状态:
a.通过调用start()进入就绪状态
b.run()就绪: 时间片到期,归还/调用yeild()
运行状态
a.cpu分配时间片进入到运行状态
阻塞状态(Blocked):
a.join() -> 造成别的线程阻塞
b.IO阻塞 -> 控制台输入/输出
c.计时等待 -> sleep(100)/wait(100)
d.无线等待 -> wait()/notifyAll()/notify()
e.锁阻塞 -> 加上同步锁/Lock锁
被终止状态: run()结束
三、线程通信
1.两个线程有共享资源,并且线程之间有动作交互
2.实现: 使用wait() 和 notify()/notifyAll()
notify() -> 唤醒线程,每次中能唤醒一个线程,只能唤醒在等待的线程
notifyAll() -> 唤醒所有正在等待的线程
注意:wait() 和 notify 需要放在同一个锁中
1.三个窗口卖同100张票
2.图片加载和显示两个线程:
1).线程1 负责图片的加载任务. 1% ~ 100% -> 加载完成
2).线程2 负责图片的显示任务.
注意: 要求图片加载完成才能显示
3.图片加载/下载 和 图片显示两个线程:
1).线程1 负责图片的加载任务. 1% ~ 100% -> 加载完成
再负责图片的下载任务. 1% ~ 100% -> 下载完成
要求: 图片显示完成后才能下载
2).线程2 负责图片的显示任务.
要求图片加载完成才能显示