2014-07-17 1 views
0

게임 룸을 관리하는 클래스가 정의되어 있습니다. 사용자가 새 룸을 만들면 고유 한 룸 번호가있는 새 룸을 생성하여 해시 세트에 추가합니다.몇 분 후에 개체를 재활용하도록 예약하는 방법

는 지금, 나는 24 시간, 또는 내 mememory

의 대부분을 지출 버려진 룸 개체가 어떻게이를 달성 할 수있는 말, HashSet의에서 해당 룸 개체를 제거하고 perfarmance 문제에 대한 객실 객체를 재활용하는 희망? 또한 성능을 향상시키기위한 제안은 매우 높이 평가 될 것입니다. 당신은 Timer를 사용하여이 스스로 할 수

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

이것이 정확히 필요한 것입니다. http://stackoverflow.com/a/3802420/544983 – Juvanis

+0

감사합니다! 하지만 맵 대신 세트를 사용하고 있습니까? 세트에 대한 그들의 모범이 무엇입니까? – Jaskey

+0

그러면 guava "cachebuilder"예제를 살펴볼 수 있습니다. – Juvanis

답변

1

다음과 같이

내 클래스입니다. 누군가 새로운 방을 만들 때마다 ID를 다시 삭제하고 public void schedule(TimerTask task, Date time)을 사용하여 실행될 작업을 예약하는 새로운 TimerTask 인스턴스를 만듭니다. 그것은 다음과 같이 보일 수 있습니다 : DeleteKeyTask 지정된 ID를 삭제 TimerTask의 사용자 지정 하위 클래스

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; 
} 

.

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)을 조회 할 수 있습니다.

+0

감사합니다!하지만 버려진 룸 오브젝트를 재활용 할 수 있다면 좋겠지 만 각 방에는 작업이 없습니다. – Jaskey

+0

@Jaskey 공간 절약에 대한 추가 정보를 제공하기 위해 내 대답을 업데이트했습니다. – Samuel

+0

사무엘, 업데이트 한 날짜를 사용하여 효율적인 샘플로 만들 수있는 코드를 리팩터링 하시겠습니까? 내 관점에서 볼 때, 모든 방의 시간표를 갖고 싶지 않다면, 새 방을 만들 때 "timer.schedule (새 DeleteKeyTask ...") 코드를 추가하면 안됩니다. , Room 객체를 사용하여 Num과 나중에 더 광범위하게 사용할 날짜를 지정해야한다고 결정했습니다. – Jaskey

관련 문제