0

I have a server where more than one client connects. Each connection spawns a new Thread, which then acts independently.

I am now facing the task of making a Lobby, where multiple WaitingRooms can be created. After 2 minutes a WaitingRoom will start the game for the players registered in a List.

Here is the problem: how can I have a timed thread? I was thinking of these solutions:

  • Creating a SingleThreadExecutor and make the WaitingRooms implement Callable, so that after 2mins I can call a get on them.
  • Creating a Thread associated to the WaitingRoom, doing so with a Wrapper class, which has a Runnable that every second decreases by one a variable "timer" until zero is reached.
  • Creating a class that has a List that has a Thread running through them, invoking a method to decrease a variable "timer".

I shall apply this clock-thing also to PlayerTurns and to Connections.

I don't want to reinvent the clock and I am sure I'm not the first person doing something like this: is there a standard way?

Warren Dew
  • 8,790
  • 3
  • 30
  • 44
Vale
  • 1,104
  • 1
  • 10
  • 29
  • There are many Questions and Answers on this topic. As discussed below, search for `ScheduledExecutorService` and see the [Oracle Tutorial](http://docs.oracle.com/javase/tutorial/essential/concurrency/exinter.html) for the modern way to do this. Search for `Timer` and `TimerTask` for the old way to do this (*not* recommended on Servlet or Java EE servers). – Basil Bourque Jul 02 '16 at 00:14

2 Answers2

1

I would use java.util.Timer and java.util.TimerTask. That way you won't have to create your own timing threads.

Warren Dew
  • 8,790
  • 3
  • 30
  • 44
  • 2
    Those are obsolete. Use a ScheduledExecutorService instead. – JB Nizet Jul 01 '16 at 22:37
  • 1
    Just because there is something newer and more complicated doesn't mean that they are obsolete. – Warren Dew Jul 01 '16 at 22:38
  • @JBNizet but doesn the ScheduledExecutorService stop and kill the thread when I do a get on it? And isn't it more complicated? – Vale Jul 01 '16 at 22:38
  • @WarrenDew can I ask you if you have a guide to follow? Or if you know where I can find an example? Meanwhile I'm looking for it myself – Vale Jul 01 '16 at 22:39
  • 1
    The Javadoc is pretty clear. Google "java util timer" and it should be one of the first links to come up. If you have specific questions after that, I'll try to answer them. – Warren Dew Jul 01 '16 at 22:41
  • @Vale which thread? Do a get() on what? No, it's not more complicated. It basically does the same thing as a Timer. – JB Nizet Jul 01 '16 at 22:42
  • @WarrenDew `Timer` is indeed supplanted by `ScheduledExecutorService`, as [its own class doc says](http://docs.oracle.com/javase/8/docs/api/java/util/Timer.html) in the 7th paragraph: “…the `ScheduledThreadPoolExecutor` … is … a more versatile replacement for the `Timer`/`TimerTask` combination”. ( a ScheduledThreadPoolExecutor is an implementation of ScheduledExecutorService) – Basil Bourque Jul 02 '16 at 00:04
  • The doc doesn't say "deprecated", so it's obviously not supplanted. – Warren Dew Jul 02 '16 at 00:08
1

Create a background Thread and use Thread.sleep() on that thread to wait for two minutes. (Note that thread.sleep() takes in milliseconds)

(I'm assuming this is a game with players)

Example (Assuming you have a method for when a player joins):

public void onPlayerJoin() {
    waitForPlayers();
}

boolean isWaiting = false;

public void waitForPlayers() {
    if (!isWaiting) {
        isWaiting = true;
        new Thread("background").sleep(millis);
        // Now that we have waited, start the game
        isWaiting = false;
        game.start();
    }
}

This method is called when a player joins. If it is already waiting, it doesn't do anything. However, if it is not waiting, it creates a thread, makes it sleep for 2 minutes, and then proceeds to begin the game.

EDIT:

Also, if you want to close the player threads before starting the game (or anywhere (If the players threads are in an ArrayList)

for (Player p : Players) {
    try { p.join(); } catch (InterruptedException e) { e.printStackTrace(); }
}