public final void wait (long millis)的解释

本文详细解析了Java中线程的wait方法,包括其作用、参数、异常处理及使用场景。介绍了如何通过wait方法使线程释放对象锁并进入等待状态,直至被唤醒或超时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public final void wait (long millis)
Since: API Level 1

Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object or until the specified timeout expires. This method can only be invoked by a thread which owns this object's monitor; see notify() on how a thread can become the owner of a monitor.
导致调用者线程等待,直到另一个线程调用notify()或者notifyAll()方法,或者指定的等待时间到达。这个方法仅仅能被拥有这个对象监视器的线程调用;查看notify()方法可以获取一个线程怎样成为拥有者的监视器。

A waiting thread can be sent interrupt() to cause it to prematurely stop waiting, so wait should be called in a loop to check that the condition that has been waited for has been met before continuing.
一个等待的线程在调用interrupt()方法后过早的停止等待,因此等待函数wait应该被放到一个循环中进行调用,每次执行循环前检查wait的条件是否还满足。

While the thread waits, it gives up ownership of this object's monitor. When it is notified (or interrupted), it re-acquires the monitor before it starts running.
在线程等待中,它将放弃对象监听器的拥有权。当它被通知或者打断时,在它重新启动前,将重新获取到监视器。

Parameters
millis  the maximum time to wait in milliseconds.
Throws
IllegalArgumentException  if millis < 0.
IllegalMonitorStateException  if the thread calling this method is not the owner of this object's monitor.
InterruptedException  if another thread interrupts this thread while it is waiting.
See Also

    * notify()
    * notifyAll()
    * wait()
    * wait(long, int)
    * Thread
例如:
    Runnable mTask = new Runnable() {
        public void run() {
            // Normally we would do some work here...  for our sample, we will
            // just sleep for 30 seconds.
            long endTime = System.currentTimeMillis() + 15*1000;
            while (System.currentTimeMillis() < endTime) {
                synchronized (mBinder) {
                    try {
                        mBinder.wait(endTime - System.currentTimeMillis());
                    } catch (Exception e) {
                    }
                }
            }

            // Done with our work...  stop the service!
            AlarmService_Service.this.stopSelf();
        }
    };
线程会阻塞到mBinder.wait(endTime - System.currentTimeMillis());位置,直到endTime等于System.currentTimeMillis(),线程才能继续执行。
外层使用一个 while (System.currentTimeMillis() < endTime)循环保证线程不会退出。

接下来,我将从代码实现的角度来为大家详细的解析Handler-Looper-MessageQueue模型 Message.java package MyMessage; import MyHandler.Handler; public class Message { public int what; public Object obj; public Handler target; public long when; public Message next; } MessageQueue.java package MyMessageQueue; import MyMessage.Message; public class MessageQueue { private Message head; // 入队方法; public synchronized void enqueueMessage(Message msg, long delayMillis) { msg.when = System.currentTimeMillis() + delayMillis; // 空队列 或 新的最早消息; if (head == null || msg.when < head.when) { msg.next = head; head = msg; notify(); return; } Message p = head; while (p.next != null && p.next.when <= msg.when) { p = p.next; } msg.next = p.next; p.next = msg; } // 出队方法; public synchronized Message next() { for (;;) { long now = System.currentTimeMillis(); if (head == null) { waitUninterruptibly(0); continue; } long diff = head.when - now; if (diff <= 0) { Message m = head; head = m.next; m.next = null; return m; } waitUninterruptibly(diff); } } private void waitUninterruptibly(long millis) { boolean interrupted = false; try { while (true) { try { if (millis == 0) { wait(); } else { wait(millis); } return; } catch (InterruptedException e) { interrupted = true; } } } finally { if (interrupted) Thread.currentThread().interrupt(); } } } Hander.java package MyHandler; import MyLooper.Looper; import MyMessage.Message; import MyMessageQueue.MessageQueue; public class Handler { private final Looper mLooper; private final MessageQueue mQueue; public Handler() { this(Looper.myLooper()); } public Handler(Looper looper) { if (looper == null) throw new RuntimeException("Can't create Handler inside thread without Looper"); mLooper = looper; mQueue = looper.mQueue; } public void sendMessage(Message msg) { msg.target = this; mQueue.enqueueMessage(msg, 0); } public void sendMessageDelayed(Message msg, long delayMillis) { msg.target = this; mQueue.enqueueMessage(msg, delayMillis); } public void post(Runnable r) { Message m = new Message(); m.obj = r; sendMessage(m); } public void dispatchMessage(Message msg) { if (msg.obj instanceof Runnable) { ((Runnable) msg.obj).run(); } else { handleMessage(msg); } } public void handleMessage(Message msg) { } } Looper.java package MyLooper; import MyMessage.Message; import MyMessageQueue.MessageQueue; public class Looper { private static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>(); public final MessageQueue mQueue; private Looper() { mQueue = new MessageQueue(); } public static void prepare() { if (sThreadLocal.get() != null) { throw new IllegalStateException("Only one Looper per thread"); } sThreadLocal.set(new Looper()); } public static Looper myLooper() { return sThreadLocal.get(); } public static void loop() { Looper me = myLooper(); if (me == null) throw new IllegalStateException("No Looper; call prepare() first"); for (;;) { try { Message msg = me.mQueue.next(); if (msg == null) continue; msg.target.dispatchMessage(msg); } catch (Exception e) { Thread.currentThread().interrupt(); break; } } } } Demo.java import MyLooper.Looper; import MyMessage.Message; import MyHandler.Handler; public class Demo { public static void main(String[] args) { // 创建并启动工作线程 new WorkerThread("WorkerThread").start(); // 给主线程一点时间确保工作线程初始化完成 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 主线程发送消息 System.out.println("MainThread: 准备发送消息"); WorkerThread.handler.sendMessage(WorkerThread.obtainMessage(1, "普通消息")); WorkerThread.handler.sendMessageDelayed(WorkerThread.obtainMessage(2, "延迟消息"), 3000); WorkerThread.handler.post(() -> System.out.println("WorkerThread: 执行Runnable任务 - " + Thread.currentThread().getName()) ); System.out.println("MainThread: 所有消息已发送"); } } class WorkerThread extends Thread { public static Handler handler; // 静态便于主线程访问 public WorkerThread(String name) { super(name); } @Override public void run() { // 初始化Looper和Handler Looper.prepare(); handler = new Handler() { @Override public void handleMessage(Message msg) { // 处理消息 System.out.println(getName() + ": 收到消息 - what=" + msg.what + ", obj=" + msg.obj); } }; System.out.println(getName() + ": Looper已准备, 等待消息..."); Looper.loop(); // 开始消息循环 } // 辅助方法创建消息 public static Message obtainMessage(int what, Object obj) { Message msg = new Message(); msg.what = what; msg.obj = obj; return msg; } }
最新发布
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值