线程笔记分享

在一个进程中,多个线程可以共享进程中的相同的内存和文件资源。
单线程:排队执行、在同一时间内,只能执行一个任务,CPU利用率大幅度降低,这是最大的缺点。
多线程:在同一时间内可以执行多个任务、这是多线程最大的优点。

实现线程的方式,继承Thread,实现Runnable接口,Thread实际上也是实现了Runnable接口,之间是多态关系,继承Thread最大的局限是java不支持多继承,所以一般建议实现Runnable接口。
线程调用start方法比较耗时,大概四个步骤,
1.通过jvm告诉操作系统创建Thread,jvm依赖的是内核线程(KLT),线程分为用户线程(ULT)和内核线程(KLT)
2.操作系统开辟内存并使用Windows SDK中的createThread()函数创建Thread对象
3.操作系统对Thread对象进行调度,已确定执行时机,cpu的执行是靠时间片的,抢到时间片了才能执行
4.Thread在操作系统中被成功执行。

线程的执行是随机性的。并不是调用了start就能立即执行。

使用常见的命令分析线程的信息,
1.在cmd中输入jps命令,找到对应的进程,然后使用jstack -l 进程ID
2.在cmd中输入jmc命令,找到对应的线程,点击MBean服务器,可以查看线程信息
3.在cmd中输入jvisualvm命令
推荐jmc命令 

多线程随机输出的原因:CPU将时间片分给不同的线程,线程获得时间片之后就执行任务。CPU在不同的线程上切换是需要消耗时间的,并不是创建的线程越多越好

使用Runnable比Thread好的原因,java不支持多继承,但可以多实现

判断线程是否还活着:isAlive

停止一个线程的方法
①stop,强行终止线程,不管当前方法有没有执行完,不推荐使用,存在无法预料的结果,而且也被标示为过期了。它会破坏原子逻辑操作,比如线程内部加了锁,调用stop方法会丢其所有的锁,导致原子逻辑不完整
②使用退出标志,让线程正常退出
③使用interrupt方法,此方法底层只是修改了线程的停止标记,如果线程正在运行,并不是立刻停止。建议使用此方法

判断线程是不是停止:isInterrupted和interrupted方法,当在sleep中的线程被调用interrupt方法时,就会放弃暂停的状态,并抛出InterruptException异常,interrupted判断当前线程是否已经中断状态,该方法具有清除状态的公功能

暂停和恢复线程:suspend和resume容易造成公共同步对象被独占,其他线程无法访问公共同步对象的结果

调用notify方法后,当前线程并不会立刻释放锁,其他wait状态的线程也不会立刻获取到锁,需要等到当前线程退出synchronized方法或者代码块。
notify方法执行的顺序与wait顺序一致,比如wait的顺序是54321,则notify唤醒的顺序也是54321(一次只能唤醒一个),notifyAll则是倒序唤醒的12345,这也不一定,依赖具体的jvm实现

猜你喜欢

转载自blog.csdn.net/dhj199181/article/details/110009405