如何在几分钟后安排回收对象

时间:2014-07-17 14:06:39

标签: java algorithm

我有一个定义的类来管理游戏室。当用户创建新房间时,我会生成一个具有唯一房间号的新房间,并将其添加到哈希集中。

现在,我希望从hashset中删除Room对象并回收Room对象以获取perfarmance问题,比如24小时,或者放弃的Room对象将花费我的大部分内存

我怎样才能做到这一点?此外,任何改善表现的建议都将受到高度赞赏。

我的课程如下:

   public class RoomService {

private RoomService(){
    super();
}

private HashSet<Room> roomSet =new HashSet<Room>();

private static RoomService instance =new RoomService();

public static RoomService getServiceInstance(){
    return instance;
}

private static Integer generateRandom(int length) {
    Random random = new Random();
    char[] digits = new char[length];
    digits[0] = (char) (random.nextInt(9) + '1');
    for (int i = 1; i < length; i++) {
        digits[i] = (char) (random.nextInt(10) + '0');
    }
    return Integer.decode(new String(digits));
}

/**
 * Generate new Room with an unique Room number
 * @return
 */
public Room newRoom(){
    Room newRoom;
    do{
        newRoom =new Room(generateRandom(4));
    }
    while(!roomSet.add(newRoom));

    return newRoom;
}}







public class Room {
private Integer roomNum;
private Date createTime=new Date();
private String creatorId;


/*
 * constructor
 */
public Room(Integer roomNum) {
    super();
    this.roomNum = roomNum;
}




@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((roomNum == null) ? 0 : roomNum.hashCode());
    return result;
}


@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Room other = (Room) obj;
    if (roomNum == null) {
        if (other.roomNum != null)
            return false;
    } else if (!roomNum.equals(other.roomNum))
        return false;
    return true;
}




//getter and setter
//
//
public String getCreatorId() {
    return creatorId;
}

public void setcreatorId(String creatorId) {
    this.creatorId = creatorId;
}

public Integer getRoomNum() {
    return roomNum;
}

public Date getCreateTime() {
    return createTime;
}

}

1 个答案:

答案 0 :(得分:1)

您可以使用Timer自行完成此操作。每次有人创建新房间时,您都会创建一个新的TimerTask实例,该实例将再次删除该ID,并使用public void schedule(TimerTask task, Date time)安排执行该任务。它可能看起来像这样:

private final Timer timer; // Initialised somewhere

public Integer newRoomNum() {
    Integer newRoomNum = ... // Create id
    Date date = ... // Create date when the id should be deleted again
    timer.schedule(new DeleteKeyTask(newRoomNum), date);
    return newRoomNum;
}

DeleteKeyTaskTimerTask的自定义子类,删除给定的ID。

private class DeleteKeyTask extends TimerTask {
    private final Integer id;

    public DeleteKeyTask(Integer id) {
        this.id = id;
    }

    @Override
    public void run() {
        // remove id
    }

您可以使用不同的方法节省空间

您可以将日期与整数键一起存储,而不是每个键都有一个任务。例如,您可以使用HashMap<Integer, Date>(或存储毫秒而不是日期)。地图的键形成您之前的设置。这些值表示密钥插入或过期的时间。

然后,您可以安排计时器删除下一个过期密钥,此时您将查找下一个过期密钥并计划删除该密钥等。这将花费您O(n)时间来计算下一个过期密钥。您的任务运行方法看起来像

public void run() {
    map.remove(id);
    Integer next = ... // Find next expiring key
    timer.schedule(new DeleteKeyTask(next), map.get(next));
}

您需要调整创建方法:

public Integer create() { // Previously newRoomNum()
    Integer newRoomNum = ... // Create id
    Date date = ... // Create date when the id should be deleted again
    if(map.isEmpty()) // Only schedule when empty
        timer.schedule(new DeleteKeyTask(newRoomNum), date);
    map.put(newRoomNum, date);
    return newRoomNum;
}

这样您只需要存储每个整数的日期。如果在计算下一个时O(n)开销太大,您可以通过使用更多空间来加快速度:使用Queue并插入新密钥。该队列将允许您检索下一个过期密钥,从而查找下一个过期密钥O(1)