ServletContext などのアプリケーション スコープ変数に、ログインしているユーザーのマップを格納できます。たとえば、認証サーブレットでは、おそらく次のようなことができます。
Map<String,String> activeUsers = request.getSession().getServletContext().getAttribute("__ONLINE_AUTHENTICATED_USERS");
//if null, context hasn't been prepared yet, create and attach a new one?2
ただし、注意が必要です。アプリケーション スコープ変数であるため、ある程度のスレッド セーフを確保する必要があります。これは、servletContext.setAttribute/getAttribute が提供するものです (たとえば、これらの操作はスレッド セーフではありません)。これは、ある種のアプリケーション ライフサイクル リスナーを使用して servletContext を「初期化」し、ユーザー マップを持つことで処理できる場合があります。これにより、set/getAttribute について心配する必要がなくなります。マップ操作自体について考える必要があります (たとえば、jucConcurrentHashMap を使用しますか?)。
また、ユーザーがログアウトしたときやセッションがタイムアウトしたときのクリーンアップ (マップからの削除など) にも注意を払う必要があります。
また、このアプローチによってユーザーが長時間ロックアウトする可能性があることも考慮する必要があります (たとえば、ブラウザーを閉じても適切にログアウトしない、マッピングがクリアされる前にセッションがタイムアウトする必要がある)。
編集:スケーラビリティについても考える必要があり、これはアプリケーションによって異なります。100 万人のオンライン ユーザーを期待していますか? それとも数千だけ?