今天学习了,线程的交互与守护线程。
再次感到什么叫做,理解与应用的不同。理解容易,应用起来确实无从下手,这感觉很是无语。
线程的交互
1,基础知识
线程交互知识点需从java.lang.Object的类的三个方法学习:
void notify():唤醒在此对象监视器上等待的单个线程。
void notifyAll():唤醒在此对象监视器上等待的所有线程。
void wait():导致当前的线程等待,直到其他线程调用此对象的notify() 方法或notifyAll() 方法。
关于等待/通知,要记住的关键点是:必须从同步环境内调用wait()、notify()、notifyAll()方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。
注意:
当在对象上调用wait()方法时,执行该代码的线程立即放弃它在对象上的锁。然而调用notify()时,并不意味着这时线程会放弃其锁。如果线程仍然在完成同步代码,则线程在移出之前不会放弃锁。因此,只要调用notify()并不意味着这时该锁变得可用。
2.多个线程在等待一个对象锁时候使用notifyAll()
在多数情况下,最好通知等待某个对象的所有线程。如果这样做,可以在对象上使用notifyAll()让所有在此对象上等待的线程重出等待区,返回到可运行状态。
在这里,我们遇到一个问题,当cpu再调用notify时,如果计算线程先执行,并在读取结果线程等待之前调用了notify()方法。那计算线程经不会再次调用notifyAll()方法。这样就时执行的线程处于死睡眠状态。
通常,解决上面问题的最佳方式是利用某种循环,该循环检查某个条件表达式,只有当正在等待的事情还没有发生的情况下,它才继续等待。
线程的调度-守护线程
守护线程与普通线程写法上基本么啥区别,调用线程对象的方法setDaemon(true),则可以将其设置为守护线程。
守护线程使用的情况较少,但并非无用,举例来说,JVM的垃圾回收、内存管理等线程都是守护线程。还有就是在做数据库应用时候,使用的数据库连接池,连接池本身也包含着很多后台线程,监控连接个数、超时时间、状态等等。
SetDaemon 方法的详细说明:
Thread t1 = newMyCommon();
Threadt2 = new Thread(newMyDaemon());
t2.setDaemon(true); //设置为守护线程
t2.start();
t1.start();