有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java应用程序跨所有会话处理bean?

希望我能有点道理,我以前从未做过这个特殊的任务

我有一个应用程序,我想在启动时创建一个bean,它有一个每30分钟运行一次的计划任务,并更新应用程序中所有会话使用的映射。我最初的想法是为这个任务创建一个应用程序范围的bean

所以这个想法是:

  1. 用户A登录。在他的地图上存储价值
  2. 用户B登录。在他的地图上存储价值
  3. 进程运行,更新映射中的所有值
  4. 用户B和A将在整个会话期间不断检查其值
  5. 注销,从映射中删除值

所以现在看起来是这样的:

@ManagedBean(eager=true, name="monitor")
@ApplicationScoped
public class MyMonitor implements Serializable {

    private static final long serialVersionUID = -1L;
    private ScheduledExecutorService scheduler; 
    private HashMap<Integer, String> myDict;

    @PostConstruct
    public void init() {
        myDict = new HashMap<Integer, String>();
        myDict.put(1, "a");
        myDict.put(2, "b");
        myDict.put(3, "c");

        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 30, TimeUnit.SECONDS);
    }

    @PreDestroy
    public void destroy() {
        scheduler.shutdownNow();
    }

    public class SomeDailyJob implements Runnable {

        @Override
        public void run() {
            System.out.println("hello world");
        }

    }

    public HashMap<Integer, String> getMyDict() {
        return myDict;
    }
    public void setMyDict(HashMap<Integer, String> myDict) {
        this.myDict = myDict;
    }
}

在另一个类中,我需要基于key从myDict检索值(这个类位于DAO层,它不是托管bean)。我尝试在该类中实例化此bean:

public class MyDAO {
    @ManagedProperty(value="#{myMonitor}")
    private MyMonitor monitor;
}

得到:

WARNING: The web application [app] is still processing a request that has yet to finish

我的问题是:

  1. 我真的应该使用ApplicationScoped bean来解决这个问题吗? 我没有EJB
  2. 我知道我还没有添加同步性, 但这安全吗?这真的有效吗

共 (1) 个答案

  1. # 1 楼答案

    您可以使用java。util。这个计时器。定义一个类

        import java.util.TimerTask;
    
        public class Monitor extends TimerTask {
    
            @Override
            public void run() {
              // do something
            }
        }
    

    然后你的类可能会被重构成类似这样的东西(我删除了其他代码以保留这个想法)

    @ManagedBean(eager=true, name="monitor")
    @ApplicationScoped
    public class MyMonitor implements Serializable {
    
        //runs as daemon thread
        private final Timer timer = new Timer(true);
        private Monitor monitor = new Monitor();
    
        @PostConstruct
        public void init() {       
           // period are in milliseconds
           timer.scheduleAtFixedRate(monitor, 0, 30*1000);
        }
    
        @PreDestroy
        public void destroy() {
           timer.cancel();
        }
    }
    

    这也将帮助您移动Monitor.run()中的大部分更新逻辑,将其与调度程序逻辑分离。我希望有帮助