Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)
本篇我们来研究一下wait()notify()notifyAll()。
DEMO1:wait()与notify()
publicclassTest{
staticclassThreadOneextendsThread{
privateCallbackmCallback;
@Override
publicvoidrun(){
work();
if(mCallback!=null){
mCallback.onResult(false);
}
}
//耗时3s
privatevoidwork(){
System.out.println("正在查询数据库1");
longstartTime=System.currentTimeMillis();
while(true){
if(System.currentTimeMillis()-startTime<3000){
continue;
}
break;
}
}
publicvoidsetCallback(Callbackcallback){
mCallback=callback;
}
publicinterfaceCallback{
voidonResult(booleanresult);
}
}
staticclassThreadTestextendsThread{
privateObjectmLock=newObject();
privateThreadOnemThreadOne;
@Override
publicvoidrun(){
workOne();
System.out.println("根据结果继续做其他事情");
}
privatevoidworkOne(){
mThreadOne=newThreadOne();
mThreadOne.setCallback(newThreadOne.Callback(){
@Override
publicvoidonResult(booleanresult){
System.out.println("查询数据库1结束,:"+(result?"有数据":"无数据"));
synchronized(mLock){
mLock.notify();
System.out.println("--ThreadTest结束等待--");
}
}
});
mThreadOne.start();
try{
synchronized(mLock){
System.out.println("--ThreadTest进入等待--");
mLock.wait();
}
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
publicstaticvoidmain(String[]var0){
ThreadTestthreadTest=newThreadTest();
threadTest.start();
}
}
DEMO1输出:
--ThreadTest进入等待-- 正在查询数据库1 查询数据库1结束,:无数据 --ThreadTest结束等待-- 根据结果继续做其他事情
注意:
使用wait()和notify()必须在获得同步锁后才能调用,若直接调用会报java.lang.IllegalMonitorStateException错误,因为状态由同步锁保护。
wait()不同于sleep()的是wait()会释放同步锁。
因为wait()和notify()是基于同步锁实现的,每个对象都有自己的同步锁,所以wait()和notify()是Object的方法,而不是Thread。
DEMO2,wait()与notifyAll():
publicclassTest{
privatestaticObjectmLock=newObject();
staticclassMyThreadextendsThread{
StringmName;
CallbackmCallback;
publicMyThread(Stringname){
mName=name;
}
@Override
publicvoidrun(){
work();
if(mCallback!=null){
mCallback.onResult(false);
}
}
//耗时3s
privatevoidwork(){
System.out.println(mName+"等待");
try{
synchronized(mLock){
mLock.wait();
}
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
publicvoidsetCallback(Callbackcallback){
mCallback=callback;
}
publicinterfaceCallback{
voidonResult(booleanresult);
}
}
staticclassThreadTestextendsThread{
@Override
publicvoidrun(){
work("db1");
work("db2");
work("db3");
try{
sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
synchronized(mLock){
System.out.println("唤醒全部");
mLock.notifyAll();
}
}
privatevoidwork(Stringname){
finalMyThreadmyThread=newMyThread(name);
myThread.setCallback(newMyThread.Callback(){
@Override
publicvoidonResult(booleanresult){
System.out.println(myThread.mName+"回来了");
}
});
myThread.start();
}
}
publicstaticvoidmain(String[]var0){
ThreadTestthreadTest=newThreadTest();
threadTest.start();
}
}
DEMO2输出:
db1等待
db3等待
db2等待
唤醒全部
db3回来了
db1回来了
db2回来了
同一个对象的wait()方法可多次在不同的线程中调用,可让不同的线程进入等待(阻塞),可以一个一个notify(),也可以调用notifyAll()一次性全部唤醒。