您的位置:首页技术文章
文章详情页

Java多线程基础 线程的等待与唤醒

【字号: 日期:2022-09-05 14:18:41浏览:48作者:猪猪

题图:花啡,豆是买咖啡机送的,花是上周阳朔旅游买的桂花,给它起了个名字,叫 Sunday。

咖啡味淡了一点点,多了一份桂花的清香。

本篇我们来研究一下 wait() notify() notifyAll() 。

DEMO1: wait() 与 notify()

public class Test { static class ThreadOne extends Thread {private Callback mCallback;@Overridepublic void run() { work(); if (mCallback != null) {mCallback.onResult(false); }}// 耗时 3sprivate void work() { System.out.println(' 正在查询数据库 1'); long startTime = System.currentTimeMillis(); while (true) {if (System.currentTimeMillis() - startTime < 3000) { continue;}break; }}public void setCallback(Callback callback) { mCallback = callback;}public interface Callback { void onResult(boolean result);} } static class ThreadTest extends Thread {private Object mLock = new Object();private ThreadOne mThreadOne;@Overridepublic void run() { workOne(); System.out.println(' 根据结果继续做其他事情 ');}private void workOne() { mThreadOne = new ThreadOne(); mThreadOne.setCallback(new ThreadOne.Callback() {@Overridepublic void onResult(boolean result) { 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 (InterruptedException e) {e.printStackTrace(); }} } public static void main(String[] var0) {ThreadTest threadTest = new ThreadTest();threadTest.start(); }}

DEMO1 输出:

--ThreadTest 进入等待--正在查询数据库 1查询数据库 1 结束,: 无数据--ThreadTest 结束等待--根据结果继续做其他事情

注意:

使用 wait() 和 notify() 必须在获得同步锁后才能调用,若直接调用会报 java.lang.IllegalMonitorStateException 错误,因为状态由同步锁保护。

wait() 不同于 sleep() 的是 wait() 会释放同步锁。

因为 wait() 和 notify() 是基于同步锁实现的,每个对象都有自己的同步锁,所以 wait() 和 notify() 是 Object 的方法,而不是 Thread。

DEMO2,wait() 与 notifyAll():

public class Test { private static Object mLock = new Object(); static class MyThread extends Thread {String mName;Callback mCallback;public MyThread(String name){ mName = name;}@Overridepublic void run() { work(); if (mCallback != null) {mCallback.onResult(false); }}// 耗时 3sprivate void work() { System.out.println(mName + ' 等待 '); try {synchronized (mLock) { mLock.wait();} } catch (InterruptedException e) {e.printStackTrace(); }}public void setCallback(Callback callback) { mCallback = callback;}public interface Callback { void onResult(boolean result);} } static class ThreadTest extends Thread {@Overridepublic void run() { work('db1'); work('db2'); work('db3'); try {sleep(2000); } catch (InterruptedException e) {e.printStackTrace(); } synchronized (mLock) {System.out.println(' 唤醒全部 ');mLock.notifyAll(); }}private void work(String name) { final MyThread myThread = new MyThread(name); myThread.setCallback(new MyThread.Callback() {@Overridepublic void onResult(boolean result) { System.out.println(myThread.mName + ' 回来了 ');} }); myThread.start();} } public static void main(String[] var0) {ThreadTest threadTest = new ThreadTest();threadTest.start(); }}

DEMO2 输出:

db1 等待db3 等待db2 等待唤醒全部db3 回来了db1 回来了db2 回来了

同一个对象的 wait() 方法可多次在不同的线程中调用,可让不同的线程进入等待(阻塞),可以一个一个 notify(),也可以调用 notifyAll() 一次性全部唤醒。

来自:http://hackeris.me/2017/05/07/thread_base_1/

标签: Java
相关文章: