2018-01-16
java的多线程
• 分类:
java
• 标签:
java
神之双手,从不留痕。我们至今不知道他的存在,但他却操控着一些微妙的连锁反应,从而影响着这个世界的进程。
进程(ps)与线程(thread)
- 进程:正在运行的程序,是系统进行资源分配的独立单位
- 线程:进程的执行路径,调度和执行的单位,单个路径单线程,多个路径多线程
本质区别:每个进程拥有自己的一套变量,而线程只是共享数据。
多进程的意义:提高CPU的使用率
多线程的意义:提高应用程序的效率
线程
线程的五大状态
新建状态:创建线程对象
待运行:线程调用
start()
之后,有执行的资格,没有执行权运行:获得cpu的执行权(当加锁保证线程安全时会进入锁池等待获取锁,即同步阻塞)
阻塞: ①等待阻塞:Object的
wait()
方法调用后, 进入等待队列,唤醒后进入锁池,获得锁后又回到待运行状态 ②同步阻塞:争抢cpu使用权,没抢到手,进入锁池等待获得锁
③其他阻塞:如
sleep()
,join()
,时间结束后进入待运行状态死亡:run,main执行结束,或因异常退出
线程的两种调度模型
- 分时调度模型:所有线程轮流使用CPU的使用全,平均分配每个线程占用cpu的时间
- 抢占式调度模型(java采用):优先级最高为10,最低为1,多个抢占,一个运行
start()
方法和run()
方法的区别
run()
方法仅仅是封装线程执行的代码,直接调用是普通方法start()
方法是启动线程,由java去调用run()
方法
线程终止的两大原因
- 当线程的
run()
执行方法体中最后一条语句后,并经由return语句返回时 - 出现没有捕获的异常时,线程将终止
产生线程安全问题
- 是否是多线程环境
- 是否有共享数据
- 是否有多条语句操作共享数据
以上三个问题同时出现会出现线程安全问题。解决方案通常为把多个语句操作共享数据的代码给锁起来,让任意时刻只有一个线程执行即可。
线程间的协作
wait()
notify()
notifyAll()
wait()
与sleep()
的区别
sleep()
来自Thread类,wait()
来自Object类- 调用
sleep()
方法的过程中,线程不会释放对象锁。而调用wait()
方法线程会释放对象锁 sleep()
睡眠后不出让系统资源,wait()
让出系统资源其他线程可以占用CPUsleep(milliseconds)
需要指定一个睡眠时间,时间一到会自动唤醒
相同点
- 在多线程环境下调用可阻塞指定的秒数,并返回
- 两者都可以调用interrupt()方法打断线程的暂停状态
不同点
- 每个对象都有一个锁来控制同步访问,
Stnchronizad
关键字可以和对象的锁交互,来实现线程的同步。sleep()
方法没有释放锁,而wait()
释放了锁,使得其他线程可以使用同步控制块或者方法 wait()
。notify()
,notifyAll()
只能在同步方法或者同步控制块中使用,而sleep()
可以在任何地方使用sleep()
必须捕获异常,而wait()
,notify,notifyAll不需要捕获异常sleep()
是线程类Thread
的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复wait()
是Object
的方法,调用会放弃对象锁,进入等待队列,待调用notify唤醒指定的线程或者notifyAll唤醒所有线程,才会进入锁池,当获得对象锁,进入运行状态
参考
- http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
- http://www.cnblogs.com/way_testlife/archive/2011/04/16/2018312.html
dzzxjl