------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
5、Lock锁机制
但是,我们出现等待的情况时,我们只想唤醒对方线程,该怎么做呢?
Jdk升级后,这个问题得到解决
查阅api文档,工具类中有一个java.util.contcurrent.locks的包。包里面,有一些常用的接口和类
其中,有一个接口叫做Lock
Lock 实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作。
使用synchronized是隐式的,而lock成为显式的。
Interface condition 是将object监视器方法(wait notify notifyAll)分解成截然不同的对象。以便通过将这些对象与任意lock实现组合使用,为每个对象提供多个等待set。
其中,lock替代了synchronized,condition替代了object对象监视器方法的使用
我们用lock和condition来替代下这个程序:
但是,发现,我们现在做的只仅仅是替代了原来的代码。
signalAll()唤醒的是所有线程,包括本方线程,并不是仅仅是对方线程。
查阅api——Lock,我们发现,一个锁上可以有多个相关的condition对象。
我们可以创建两个condition对象,让他们分别代表生产者和消费者
Jdk1.5.0中提供了多线程升级解决方案
将同步synchronized替换成了显示的lock操作。
将object中的wait,notify,notifyAll,替换了condition对象。
该对象可以通过lock.newCondition来创建。
在该示例中,实现了本方只唤醒对方的操作
Synchronized和lock机制的区别“
synchronized机制中,一个锁只对应一个wait和notify方法
而lock机制中,一个锁可以对应多个condition对象,也就是对应多个wait和notify方法
一定程度避免死锁。
记住:释放锁的动作,一定要执行
6、停止线程
1)停止线程的原理
我们知道,线程里面一般都要写循环。那么如何让线程停止,我们需要再了解一下。
我们需要查阅api文档中关于thread类中的方法。有一个stop方法,但是已经过时。虚拟机不再识别了。
不再使用的原因,是它里面会有一些bug:不管什么原因,就使线程挂掉。
还有suspend方法,也是一样,这方法一运行,会发生死锁。
那么,没有了stop方法,我们咋让线程停止呢?
我们需要先了解下线程停止的原理:就是要让run方法结束。
原理:
开启多线程运行,运行代码通常是循环结构
只要控制住循环就可以让run方法结束,也就是线程结束。
代码
原因:Main线程执行完了,改变了标记,但是,自定义的两个线程读到run方法内的wait()中,全部冻结了,这时,主线程已经执行完,那两个线程还不能活过来。就出现了上述结果。
特殊情况
当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
发生这种特殊情况,我们可以强制结束
Thread类中为我们提供一个方法interrupt()中断线程。
注意:中断状态绝对不是停止线程。Stop方法才是停止线程。
Interrupt方法是强制清除线程的冻结状态,让线程恢复到运行状态中来。
0线程恢复到运行状态,处理异常后,又到while循环中判断,标记为真,又读到wait(),冻结了。
但是,只要线程能恢复,离结束就不远了。
3)总结:
A 当没有指定的方式,让冻结的线程恢复到运行状态时,这时需要对冻结状态进行清除,强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。用方法interrupt();
B定义循环结束标记
因为线程运行代码一般都是循环,只要控制了循环即可。
C使用interrupt(中断)方法。
该方法是结束线程的冻结状态,使线程回到运行状态中来。
注:stop方法已经过时不再使用。
7、守护线程
void setDaemon(boolean on)
将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,jvm退出。
该方法必须在启动线程前调用。
守护线程或者用户线程,其实就是后台线程。
当一个线程被标记为后台线程时,它将会与前台线程共同抢夺cpu资源。它开启运行都没有区别,只有结束有区别。
当所有前台线程都结束,后台线程会自动结束。
8、多线程中的join方法
Public final void join() throws InterruptedException
等待该线程终止。
Join方法的应用
程序开发中,我们可以临时加入一个线程,这个线程运算完,另一个线程继续运算。
Join()特点:
当A线程执行到了B线程的join方法时,a 线程就会等待,等B线程都执行完,a才会执行。
Join用来临时加入线程执行。
9、多线程优先级yield方法
1)概念
优先级:代表着抢夺资源的频率。
谁的优先级高,cpu就会多执行谁。
Thread类中的setPriority(int newPriority)更改线程的优先级。
所有线程包括主线程,优先级都是5.优先级一共10级。
2)一般设置三种
MAX_PRIORITY 10 最高优先级
MIN_PRIORITY 1 最低优先级
NORM_PRIORITY 5 默认优先级
优先级最高,但并不代表,cpu不会执行别的线程。
yield()暂停当前正在执行的线程对象,并执行其他线程。
11、线程应用
实际开发中,什么时候用多线程呢?
当程序中有多个循环,并且都相互独立,就可以用多线程,可以大大提高程序运行效率。
多用匿名内部类来实现线程创建。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------