by:天亮爬虫
1、何为多线程?
为了提高计算机的处理效率,在一个进程中,并发或并行使用多个线程处理自己的计算任务。
重点在于更充分利用计算机的各个环节的各种资源,从而提高计算效率。
2、多线程为何会盛行?
主要是计算机内部资源的不平衡性,主要是指速度不一。
CPU、高速缓存、内存、磁盘IO等部分的处理速度不一致导致的
3、java中,多线程实现的方式?
继承Thread线程类
实现Runnable接口
没有谁优谁劣,看习惯,和应用场合。多建议用实现接口形式。
4、多线程的关键问题
4.1 线程同步
synchronized:对象锁关键词
wait: 线程在某对象处等待,会释放对象锁
notify:唤醒等待在该对象上的一个线程,该线程是随机挑出来的,无规律,即不公平。
notifyAll:唤醒所有等待在该对象的线程,然后他们去竞争对象锁,优胜者得锁后执行,败者继续wait
**上面三个方法来自Object
sleep:睡眠一段时间,单位为ms,此时若有线程锁,并不释放。
yield:正在执行当中的线程,让出cpu给其它线程执行,从而使自己进入下一轮的cpu竞争。
join:等待当前线程执行完毕,其他进程进行等待。
4.2 死锁问题
原因:程序编写bug导致的。
即编程时,对计算机资源的分配不合理,形成循环(环路)的,即"你等我,我也等你,但老死得不到彼此想要的“
如线程t1先拿到对象A的锁后想拿对象B的锁,
而线程t2先拿到对象B的锁后,想拿对象A的锁,
此时是最经典的死锁案例。
4.3 锁的粒度问题
一般对象锁:即锁住一个指定的简单对象。
方法锁:包括,静态方法锁,即相当于锁住当前类所属的synchrnized(类.class)。
非静态方法锁,即锁住当前对象,相当于synchrnized(this)
类锁:即静态方法锁的作用,直接使用synchrnized(类.class) 即当前类的字节码文件
总结:粒度越小,效率越高,相应的编程难度也会复杂一些,视具体情况和个人水平而定。
5、线程优先级
线程的调度与设置优先级,优先级越高,抢占CPU的概率越高。
6、经典demo
5.1 死锁程序
5.2 生产者和消费者问题
7、将wait,notify,notifyall方式改成sleep+while循环+状态标志的方式。
为什么要改:
原因: wait,notify,notifyall这种方式够灵活,省资源,但不好控制,
很容易让开发者产生死锁,且同步代价偏高。
而且维护成本也高。
程序的可控性下降,体现在直接阻塞掉当前线程。
sleep和wait的关键区别:
wait时,线程锁是释放的。
sleep时,线程锁是不释放的。
一般来说,有synchronized时,sleep都放在其代码块的外部。
而wait时,wait代码一定要在synchronized之内。
8、守护线程
**重要:守护线程的设计与实现(略)
这里的守护线程,是指为工作线程做相关统计、汇总、输出日志、或系统操作
等功能的独立线程。