目录
前沿:撰写博客的目的是为了再刷时回顾和进一步完善,其次才是以教为学,所以如果有些博客写的较简陋,是为了保持进度不得已而为之,还请大家多多见谅。
1.为什么有多线程?
多线程能够更有效地利用CPU和安排业务执行顺序,并且在实际开发中更好地分配和细化工作。
2.多线程如何实现这些功能?
1.通过继承Thread类 or 实现接口Runnable 实现多线程
-
但实际上仍然是使用Thread类,实现Runnable接口,并创建Thread类传递Runnable目标参数。
-
通过在run()方法中写相应多线程的运行业务,当有资源时才能够调动。
2.保证线程合理轮流使用资源
-
yield()重新竞争的机会;系统的线程调度器重新调度一次
3.依次or优先级执行多线程
-
业务优先级可通过setPriority()
-
先后顺序:join()等待该线程终止再加入竞争,并且可传参设置等待最大时间后加入竞争资源。
-
调用join()获得该资源,其他线程等待该线程终止后再竞争。
-
-
等待唤醒机制:生产者与消费者问题
-
wait和sleep等待状态
-
sleep停止后,同时要锁住该资源,达到保护该资源的效果。
-
wait金进入等待状态后,将释放资源让其他线程竞争。
-
sleep是Thread的静态方法;而wait则是Object类中声明的,因其是被锁对象调用,其类型是所有对象。
-
-
notify(All)
-
3.多线程在运用中存在什么问题?
-
线程安全问题
-
创建多个线程调用通过run()方法时,则可能会出现调用时的值,不够多个线程同时使用。
-
就像购买电影票功能,三个多线程同时购买。
-
局部变量不共享 or 实例变量不共享
-
若是定义非静态变量,则将会出现三个多线程独自创建变量,各自购买100张票,共300张的情况。
-
-
静态共享不及时
-
若是定义静态变量,虽然变量是共享的,但到后期票数不够时,每个线程读取数据时是够的票,但当他们买时其实已经没票了。
-
-
-
解决方案:同步锁,即对于存在线程安全问题的代码,每次只能一个线程占用该资源。
-
本质仍然是牺牲一定效率,降低业务的犯错率;即锁的代码块越少且能够解决安全问题,则牺牲的效率也小。
-
-
-
4.多线程的生命周期是怎样的?
-
JDK1.5之前:新建new→就绪Runnable→运行Running→死亡stop()/Error 或 Exception/run()
-
阻塞Blocked、Runnable和Running形成小循环
-
-
JDK1.5之后:阻塞Blocked分成三种状态:BLOCKED、WAITING、TIMED_WAITING
-
Blocked竞争失败导致的锁
-
TIMED_WAITING调用等待方法,需等待设置时间后才能竞争;WAITING则是没有设定时间的等待,需要被唤醒才能竞争。
-
Thread类的sleep或join,Object类的wait,LockSupport类的park方法
-
-