shutdown thread分析

Android shutdown thread 

  • namespace is "package com.android.internal.app"
  • design pattern is singleton
  • 提供了公有静态成员函数

        public static void shutdown(final Context context, boolean confirm)

    confirm 输入变量决定是否弹出关机确认对话框。
    该函数只能被一个线程调用。一旦执行,其他调用将被忽略。

    该函数的常规调用是

    public class PhoneWindowManager implements WindowManagerPolicy {
    
        private final Runnable mPowerLongPress = new Runnable() {
            public void run() {
                // The context isn't read
                if (mLongPressOnPowerBehavior < 0) {
                    mLongPressOnPowerBehavior = mContext.getResources().getInteger(
                            com.android.internal.R.integer.config_longPressOnPowerBehavior);
                }
                switch (mLongPressOnPowerBehavior) {
                case LONG_PRESS_POWER_NOTHING:
                    break;
                case LONG_PRESS_POWER_GLOBAL_ACTIONS:
                    mPowerKeyHandled = true;
                    performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                    sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
                    showGlobalActionsDialog();
                    break;
                case LONG_PRESS_POWER_SHUT_OFF:
                    mPowerKeyHandled = true;
                    performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                    sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
                    ShutdownThread.shutdown(mContext, true);
                    break;
                }
            }
        };
    
    }


  • shutdown()将调用私有静态成员函数

        private static void beginShutdownSequence(Context context) 

    禁止设备进入 sleep 模式
    禁止设备 LCD 进入关闭状态。
    启动关机线程

  • 线程处理函数广播 Intent.ACTION_SHUTDOWN 消息。

    并设定超时时间。当time out 后,直接继续强制关机流程。

        // maximum time we wait for the shutdown broadcast before going on.
        private static final int MAX_BROADCAST_TIME = 10*1000;
    


  • 强制关机流程将依次关闭
    • ActivityManager
    • Bluetooth
    • Phone 1 radio
    • Phone 2 radio
    • 循环等待time out 来关闭 Bluetooth, Phone1 radio, Phone2 radio
    • MountService

  • 最后进行扫尾工作

        public static void rebootOrShutdown(boolean reboot, String reason) {
    • 选择是否 reboot
    • 选择是否 vibrate

### Redisson 客户端已关闭问题的原因及解决方案 当遇到 `Redisson client is shutdown` 错误时,通常意味着尝试在一个已经关闭的 Redisson 客户端实例上执行操作。这可能是由于程序逻辑中的某些部分提前调用了 `shutdown()` 方法,或者是客户端异常终止所致。 #### 1. 错误原因分析 - **重复调用 `shutdown()`**: 如果在同一应用程序的不同地方多次调用了 `redisson.shutdown()`,那么后续再试图使用该客户端将会抛出此异常[^1]。 - **未正确管理生命周期**: 当应用结束前未能妥善处理 Redisson 客户端资源回收流程,可能导致其被过早销毁。 - **并发环境下的竞争条件**: 在多线程环境下,如果多个线程同时访问同一个 Redisson 实例,并且其中一个线程意外地触发了关闭动作,则其他正在使用的线程也会受到影响而报错[^3]。 #### 2. 解决策略 为了有效解决这个问题,可以从以下几个方面入手: ##### a. 防止不必要的 `shutdown` 确保只有一处负责显式调用 `shutdown()` 来清理资源,并将其放置于合适的位置,比如在 JVM 关闭钩子中或 Spring 应用上下文摧毁监听器内。 ```java Runtime.getRuntime().addShutdownHook(new Thread(() -> { if (!redisson.isShuttingDown()) { redisson.shutdown(); } })); ``` ##### b. 单例模式创建 RedissonClient 采用单例设计模式来保证整个项目仅存在唯一的一个 Redisson 连接池实例,从而减少因共享不当带来的风险。 ```java public class RedissonUtil { private static volatile RedissonClient instance; private final Object lock = new Object(); public static RedissonClient getInstance(Config config){ if (instance == null || !instance.isAlive()){ synchronized(lock){ if(instance==null||!instance.isAlive()) instance=Redisson.create(config); } } return instance; } } ``` ##### c. 检查并重连机制 对于长时间运行的应用来说,在捕获到此类异常之后,应该考虑实现自动检测和重新建立连接的功能,以提高系统的健壮性和可用性[^4]。 ```java try{ // 执行具体的操作... }catch(IllegalStateException e){ if(e.getMessage().contains("is shutdown")){ log.warn("Detected that the current Redisson client has been closed, attempting to reconnect..."); // 清理旧实例 if(redisson != null && !redisson.isShutdown()){ try{ redisson.shutdown(); }catch(Exception ignore){} } // 获取新的实例 redisson = Redisson.create(config); // 继续之前的业务逻辑 ... }else throw e; } finally{ // 确保最终总是能安全断开连接 if(redisson!=null&&!redisson.isShutdown()){ redisson.shutdown(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值