等待/通知状态的变化

public class WaitNotify {

    static Object lock = new Object();

    static boolean flag = true;

    public static void main(String[] args) throws InterruptedException {
        Thread waitThread = new Thread(new Wait(), "WaitThread");
        waitThread.start();
        TimeUnit.SECONDS.sleep(1);
        Thread notifyThread = new Thread(new Notify(), "notifyThread");
        notifyThread.start();
    }

    static class Wait implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                while (flag) {
                    System.out.println(Thread.currentThread() + "flag is true. wait@" + LocalDateTime.now());
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread() + "flag is false. running@" + LocalDateTime.now());
            }
        }
    }


    static class Notify implements Runnable {
        @Override
        public void run() {
            //加锁
            synchronized (lock){
                System.out.println(Thread.currentThread() + "hold lock. notify@" + LocalDateTime.now());
                //获取到lock锁之后,notifyAll,修改flag
                lock.notifyAll();
                flag = false;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock){
                System.out.println(Thread.currentThread() + "hold lock. notify@" + LocalDateTime.now());
                try {
                    Thread.sleep(50000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}
static class Notify implements Runnable {
    @Override
    public void run() {
        //加锁
        synchronized (lock){
            System.out.println(Thread.currentThread() + "hold lock. notify@" + LocalDateTime.now());
            //获取到lock锁之后,notifyAll,修改flag
            lock.notifyAll();
            flag = false;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (lock){
            System.out.println(Thread.currentThread() + "hold lock. notify@" + LocalDateTime.now());
            try {
                Thread.sleep(50000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

}

在这里插入图片描述



WaitThread首先获得了对象的锁,然后调用对象的wait()方法,释放锁,进入了等待队列中,线程状态为waiting;NotifyThread获得了对象的锁,并调用对象的notify()方法,将WaitThread从等待队列移到同步队列中,此时WaitThread的状态变为阻塞Blocked,等待NotifyThread执行完之后释放锁之后WaitThread获取到锁之后0从wait()方法返回并继续执行。
在 Kotlin 中实现等待某个状态变化后执行操作的机制,可以使用协程(coroutines)与 `suspend` 函数结合 `MutableStateFlow` 或 `CompletableDeferred` 等异步结构。以下是一些常见的实现方式: ### 使用 `StateFlow` 监听状态变化 `StateFlow` 是一种共享的、可集的状态容器,适合用于监听状态变化并触发后续操作。 ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { // 定义一个可变的状态流,初始值为 "Initial" val stateFlow = MutableStateFlow("Initial") // 启动一个协程来监听状态变化 launch { stateFlow .filter { it == "Changed" } // 当状态变为 "Changed" 时触发 .collect { println("State changed to: $it, executing operation.") } } // 模拟延迟后更改状态 delay(1000L) stateFlow.value = "Changed" // 确保主线程不会提前退出 delay(2000L) } ``` 上述代码中,通过 `filter` 操作符监听状态流的变化,当状态变为 `"Changed"` 时,执行相应的操作。 ### 使用 `CompletableDeferred` 实现一次性状态等待 如果你只需要等待一次性的状态变化(例如任务完成),可以使用 `CompletableDeferred` 来实现。 ```kotlin import kotlinx.coroutines.* fun main() = runBlocking { val deferred = CompletableDeferred<String>() // 启动一个协程等待状态变化 launch { val result = deferred.await() println("Received result: $result") } // 模拟延迟后设置结果 delay(1000L) deferred.complete("State Changed") // 确保主线程不会提前退出 delay(2000L) } ``` 在这个例子中,协程会挂起直到 `deferred.complete()` 被调用,之后继续执行后续操作。 ### 使用 `Channel` 进行状态通知 如果你需要多个状态更新或事件驱动的通知机制,可以使用 `Channel`。 ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* fun main() = runBlocking { val channel = Channel<String>() // 启动一个协程监听通道消息 launch { for (msg in channel) { println("Received message: $msg") } } // 发送状态变化的消息 launch { delay(1000L) channel.send("State Changed to A") delay(1000L) channel.send("State Changed to B") } // 确保主线程不会提前退出 delay(3000L) } ``` 这种方式适用于需要多次通知或广播状态变化的场景。 ### 结合 `select` 表达式监听多个状态源 如果需要同时监听多个状态源(如多个 `Deferred` 或 `Channel`),可以使用 `select` 表达式[^2]。 ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.selects.* fun main() = runBlocking { val deferred1 = async { delay(1500L); "Result 1" } val deferred2 = async { delay(1000L); "Result 2" } val result = select<String> { deferred1.onAwait { it } deferred2.onAwait { it } } println("First completed result: $result") } ``` 这段代码展示了如何选择最先完成的状态并执行相应操作。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壹氿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值