優先度が最も高いメッセージを最初に送信する必要がありますので、PriorityQueue
を使用します。重要なメッセージが届いた場合にメッセージキューに追加
ただし、キューもソートセットのように動作します。したがって、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();
}
}
、我々はそのためのインスタンス変数を宣言するように、データ構造がメッセージの最低優先度の値を認識することにしたいです。着信メッセージの優先度がチェックされ、この優先度が格納された値よりも低い場合、格納された値が更新されます。送信されたメッセージを報告するには、クラスの使用が必要です。データ構造の他のメンバが削除されたものと同じ優先度を持たない場合、次の要素の優先度が格納された優先度になります。
2つのスレッドが実装されたキューを共有します。 1つのスレッドがデータベースからデータをフェッチし、それらをキューに挿入します。もう一方はキューを読み取り、最も低い優先度の番号を持つ最優先のメッセージを送信します。キューは最小優先度値を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