title: Will creating a thread for every user of my API scale well?
body: <p>I am building an API that will interact with the Spotify API in Java Spark. I went with the Authorization Code Flow for the token management - which means that the token will be valid for an hour (for a given user), and then needs to refresh.</p>
  
  <p>For every user that connects their Spotify account, I create a Timer that will check if the user was active after 50 minutes:</p>
  
  <p>If yes -> I refresh the user's token.
  If no -> I delete the user together with the user's token, which means that they will have to login again if they want to use my service (for storage purposes).</p>
  
  <p>I also keep a HashMap with a User-object, with various information from every user like their profile names, images, playlists etc. This is also deleted from the HashMap if the check from the timer proves that this user was inactive.</p>
  
  <p><strong>The PROBLEM:</strong>
  Every Timer-object creates a new Thread. If there was, theoretically, thousands of users using my service, there would be thousands of threads... My intuition tells me that this is unacceptable. I can not seem to wrap my head around this. How should I go about to keep track of when 50 minutes has passed for every user, while maintaining as few threads as possible and not "over-powering" the API? Any tips would be appreciated!</p>
  
  <p>Code:</p>
  
  <pre><code>package Authentication;
  
  import Spotify.Users.UserSessions;
  import java.util.Date;
  import java.util.Set;
  import java.util.Timer;
  import java.util.TimerTask;
  
  public class RefreshTokens extends TimerTask {
      private UserSessions userSessions;
      private Authentication authentication;
      private String currentUserSession;
      private Timer timer = new Timer(true);
  
      public RefreshTokens(UserSessions userSessions, Authentication authentication, String currentUserSession) {
          this.userSessions = userSessions;
          this.authentication = authentication;
          this.currentUserSession = currentUserSession;
      }
  
      public void startAutomaticProcess() {
          timer.schedule(this, 20000, 20000); //runs every 20 seconds for testing purposes
      }
  
      @Override
      public void run() {
          System.out.println("Automatic process started: " + new Date());
          refresh();
      }
  
      private void refresh() {
          if (userSessions.contains(currentUserSession)) {
              if (userSessions.get(currentUserSession).isActive()) {
                  authentication.refreshToken(userSessions.get(currentUserSession));
              } else {
                  System.out.println("User was not active enough and has been removed from the server.");
                  System.out.println("----------");
                  System.out.println("Size of HashMap before: " + userSessions.getHashMap().size());
                  userSessions.getHashMap().remove(currentUserSession);
                  System.out.println("Size of HashMap after: " + userSessions.getHashMap().size());
                  timer.cancel();
                  timer.purge();
              }
          }
      }
  }
  </code></pre>
  
  <p>I create a new instance of this class for every new user and call the startAutomaticProcess() method.</p>