Reputation: 38
Some clarification before we begin, I wrote this code plaintext so excuse some inconsistencies, this is basically some parts of code from my game, in my game players have the ability to send teleport request to one another and the receiving player (of the request) can either deny or accept that request. But I don't want that request to stay in the system forever, so I thought of making a task that will remove the info that "relates" the players.
To start off here is my base Player interface.
public interface Player {
void sendMessage(String message);
String getName();
UUID getUUID();
}
Here is the entire implementation of my Player interface.
public class HumanPlayer implements Player{
private final String name;
private final UUID uuid;
public HumanPlayer(String name, UUID uuid) {
this.name = name;
this.uuid = uuid;
}
@Override
public void sendMessage(String message) {
System.out.println(getName() + " -> " + message);
}
@Override
public String getName() {
return name;
}
@Override
public UUID getUUID() {
return uuid;
}
static HashMap<UUID, UUID> requests = new HashMap<UUID, UUID>();
public void request(HumanPlayer target) {
if(requests.get(uuid) == null) {
if(requests.get(target.getUUID()) == null) {
requests.put(uuid, target.getUUID());
requests.put(target.getUUID(), uuid);
sendMessage("You sent a request to " + target.getName());
new Timer().schedule(new TimerTask() {
@Override
public void run() {
requests.put(uuid, null);
requests.put(target.getUUID(), null);
sendMessage("Looks like your request timed out.");
target.sendMessage("Looks like your request timed out.");
}
}, 1000L);
}else {
sendMessage(target.getName() + " has a request already.");
}
}else {
sendMessage("You have a request already.");
}
}
}
What I want you to check specifically is this method.
public void request(HumanPlayer target) {
if(requests.get(uuid) == null) {
if(requests.get(target.getUUID()) == null) {
requests.put(uuid, target.getUUID());
requests.put(target.getUUID(), uuid);
sendMessage("You sent a request to " + target.getName());
new Timer().schedule(new TimerTask() {
@Override
public void run() {
requests.put(uuid, null);
requests.put(target.getUUID(), null);
sendMessage("Looks like your request timed out.");
target.sendMessage("Looks like your request timed out.");
}
}, 1000L);
}else {
sendMessage(target.getName() + " has a request already.");
}
}else {
sendMessage("You have a request already.");
}
}
(Another clarification, the HashMap actually is initialized depending on the number of players in the Game e.g. SomePlayerUUID -> null)
Looks like it hangs and doesn't really remove the info from the HashMap.
And for completion this is my Main class.
public class Main {
public static void main(String[] args) {
HumanPlayer p1 = new HumanPlayer("Test", UUID.randomUUID());
HumanPlayer p2 = new HumanPlayer("Test2", UUID.randomUUID());
p1.request(p2); // Here the request happens properly.
p1.request(p2); // Here player p1 is notified that p2 has a request already.
}
}
Now, what I think might be the problem is that, after the method is run the references of the players are actually eligible for the GC(? probably). I need to somehow pass the player references in for processing, do I create new references or use a lambda expression?
Here is some console output.
Test -> You sent a request to Test2
Test -> You have a request already.
Test -> Looks like your request timed out.
Test2 -> Looks like your request timed out.
BUT the execution doesn't end after that and the Java program keeps "running" I have to forcefully terminate it.
Upvotes: 0
Views: 72
Reputation: 111259
In Java, threads have a flag called "daemon" that tells the JVM if it's ok to exit while the thread is running. Timer
by default creates a "non-daemon" thread, meaning the JVM will wait for the Timer thread to stop.
You can make Timer
create a daemon thread instead, by passing a parameter to the constructor.
new Timer(true).schedule(new TimerTask() {
...
}, 1000L);
Nothing in your program is stopping the Timer thread. You can request to stop the thread by calling the Timer.cancel method.
Upvotes: 1