You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Timer引发NullPointerException:判断object非空后被置null是否可能?

问题描述

有一个名为foo的Swing类对象(每秒显示时间的窗口),核心代码如下:

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    
    @Override
    public void run() {
        
        if(object != null){
              object.getProperty(); // 此处抛出NullPointerException
        }
    }
 }, 0, 1000);

另一个类中会执行:

foo.setObject(null);

请问是否存在执行完if(object != null)判断后、调用object.getProperty()之前,另一个类中的foo.setObject(null)被执行的情况?


回答

是的,这种情况完全可能发生,本质是多线程环境下的竞态条件导致的:

  • TimerTask的run方法运行在Timer的后台线程,而foo.setObject(null)是在另一个独立线程(比如Swing事件调度线程或业务线程)执行,两个线程会抢占CPU时间片。
  • 当后台线程刚完成object != null的非空检查,CPU时间片切换到执行setObject(null)的线程,把object置为null;等切回后台线程执行object.getProperty()时,object已经是null,自然抛出NullPointerException。

解决方法

可以通过以下几种方式避免这个问题:

  • 局部变量缓存(轻量首选):把object先赋值给线程栈内的局部变量,局部变量不会被其他线程修改,后续操作直接用这个局部变量:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    
    @Override
    public void run() {
        Object localObj = object; // 缓存到局部变量
        if(localObj != null){
              localObj.getProperty();
        }
    }
 }, 0, 1000);
  • 同步锁:给object的读写操作加同一锁,保证检查和调用的原子性:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    
    @Override
    public void run() {
        synchronized (foo) { // 使用foo作为锁对象
            if(object != null){
                  object.getProperty();
            }
        }
    }
 }, 0, 1000);

// 对应的setObject方法也要加同步
public synchronized void setObject(Object obj) {
    this.object = obj;
}
  • 原子引用:用AtomicReference包装object,利用原子操作保证线程安全:
private AtomicReference<Object> objectRef = new AtomicReference<>();

// TimerTask中的代码
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    
    @Override
    public void run() {
        Object localObj = objectRef.get();
        if(localObj != null){
              localObj.getProperty();
        }
    }
 }, 0, 1000);

// 设置方法
public void setObject(Object obj) {
    objectRef.set(obj);
}

内容的提问来源于stack exchange,提问作者Javi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:04:56