우선 순위가 가장 높은 메시지를 먼저 보내야합니다. 따라서 우리는 용도로 PriorityQueue
을 사용합니다.더 중요한 메시지가 들어오는 경우 메시지 대기열에 추가
PriorityQueue<MessageData> queue = new PriorityQueue<MessageData>();
그러나 우리는 또한 대기열이 정렬 된 집합처럼 행동하기를 원합니다. 따라서 PriorityQueue
을 수정하여 기존 멤버를 반복하는 삽입을 무시합니다.
import java.util.Comparator;
import java.util.PriorityQueue;
public class PrioritySet<E> extends PriorityQueue<E> {
private static final long serialVersionUID = 34658778L;
public PrioritySet() {
super();
}
public PrioritySet(int initialCapacity, Comparator<? super E> comparator) {
super(initialCapacity, comparator);
}
@Override
public boolean offer(E e) {
boolean isAdded = false;
if(!super.contains(e)) {
isAdded = super.offer(e);
}
return isAdded;
}
}
이제 데이터 구조의 앱 특정 구현.
import java.util.Comparator;
public class MessagePrioritySet extends PrioritySet<MessageData> {
private static final long serialVersionUID = 34658779L;
private int minPriorityNumber;
public MessagePrioritySet() {
super();
}
public MessagePrioritySet(int initialCapacity, Comparator<MessageData> comparator) {
super(initialCapacity, comparator);
}
public synchronized int getMinPriorityNumber() {
return minPriorityNumber;
}
public synchronized void setMinPriorityNumber(int minPriorityNumber) {
this.minPriorityNumber = minPriorityNumber;
}
@Override
public synchronized boolean offer(MessageData notification) {
boolean isAdded = super.offer(notification);
if (notification.getPriority() < minPriorityNumber)
minPriorityNumber = notification.getPriority();
return isAdded;
}
public synchronized void reportSent(MessageData notification) {
MessageData nextMessageData = peek();
if (nextMessageData == null)
minPriorityNumber = 0;
else if (nextMessageData.getPriority() > notification.getPriority())
minPriorityNumber = nextMessageData.getPriority();
}
}
여기서 우리는 데이터 구조가 메시지의 최소 우선 순위 값을 알고 있기 때문에 이에 대한 인스턴스 변수를 선언합니다. 들어오는 메시지의 우선 순위가 검사되고이 우선 순위가 저장된 값보다 낮 으면 저장된 값이 업데이트됩니다. 보낸 메시지를보고하려면 클래스를 사용해야합니다. 데이터 구조의 다른 멤버가 우선 순위가 낮은 멤버가없는 경우 다음 요소의 우선 순위가 저장된 우선 순위가됩니다.
두 스레드가 구현 된 큐를 공유합니다. 한 스레드는 데이터베이스에서 데이터를 가져 와서 큐에 삽입합니다. 다른 하나는 대기열을 읽고 우선 순위 번호가 가장 낮은 우선 순위가 가장 높은 메시지를 보냅니다. 대기열은 최소 우선 순위 값을 0으로 설정하고 데이터베이스에서 데이터를 가져 오는 스레드는 저장된 최소값이 0이 아닌 경우 대기열에 저장된 최소값보다 낮은 우선 순위 값을 가진 행을 읽습니다. 대기열의 현재 메시지가 전송되는 동안 이미 대기열에있는 것보다 중요한 새 메시지 만 대기열에 추가됩니다.
스레드의 while 루프에서의 작업은 원자 적이어야한다고 생각합니다. 어떻게 원자를 만드는 법을 알려줄 수있는 사람에게 감사드립니다.
private void startMptSender() {
sleepInterval = 1000;
final MessagePrioritySet messagePrioritySet = new MessagePrioritySet();
Runnable mptReader = new Runnable() {
@Override
public void run() {
while (true) {
List<MessageData> messageDataList;
if (messagePrioritySet.getMinPriorityNumber() == 0)
messageDataList = messageDao.readSMSMpt();
else
messageDataList = messageDao.readSMSMpt(messagePrioritySet.getMinPriorityNumber());
for (MessageData messageData : messageDataList) {
messagePrioritySet.offer(messageData);
}
try {
Thread.sleep(sleepInterval);
} catch (InterruptedException ie) {
}
}
}
};
executor.execute(mptReader);
Runnable mptPusher = new Runnable() {
@Override
public void run() {
while (status) {
if (messagePrioritySet.size() > 0) {
while (messagePrioritySet.size() != 0) {
MessageData noti = messagePrioritySet.remove();
mptSender.sendSms(noti);
messageDao.markNotificationAsRead(noti.getSyskey());
messagePrioritySet.reportSent(noti);
try {
Thread.sleep(sleepInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
try {
Thread.sleep(sleepInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
executor.execute(mptPusher);
}
은}
힌트 : 놀랍게도 (잠재적으로) 작업 코드에 대한 검토 요청은 codereview.stackexchange.com으로 이동해야합니다. 그렇다면 : ** 짧은 ** 문장을 쓰는 것이 좋습니다. 기본 주제 동사 대상과 같습니다. 나는 당신이 우리에게 무엇을 말하려고하는지 파악하는 데 어려움이 있습니다. 그 이유는 주로 여기저기서 문장에 내용을 계속 추가하여 진행 상황을 파악하기가 어렵 기 때문입니다. – GhostCat
@GhostCat 그래서이 질문을 코드 검토로 옮기는 방법이 있습니까? –
아직 답변을 드리고있는 질문이 여기에 있습니다. 그래서 "검토"부분을 제거하고 그 사이트에 다른 요청을하는 질문을 제안합니다. – GhostCat