我有一個類,其中我的add
方法被多個線程調用以填充clientidToTimestampHolder
LinkedBlockingQueue。然後在下面的類中,我開始一個後臺線程,每30毫秒運行一次並調用processData()
方法,將clientidToTimestampHolder
排除到Map List,然後迭代該List以通過調用適當的方法將數據發送到不同的服務。當底層方法返回時,並行地執行for循環而不是順序排列
我可以用不同的時間戳獲得相同的userid多次,所以這就是爲什麼我使用LinkedBlockingQueue和map。
public class Handler {
private final ScheduledExecutorService executorService = Executors
.newSingleThreadScheduledExecutor();
private final LinkedBlockingQueue<Map.Entry<String, Long>> clientidToTimestampHolder =
new LinkedBlockingQueue<>();
private static class Holder {
private static final Handler INSTANCE = new Handler();
}
public static Handler getInstance() {
return Holder.INSTANCE;
}
private Handler() {
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
processData();
}
}, 0, 30, TimeUnit.MILLISECONDS);
}
// called by multiple threads to populate clientidToTimestampHolder map
public void add(final String clientid, final Long timestamp) {
clientidToTimestampHolder.offer(Maps.immutableEntry(clientid, timestamp));
}
// called by single background thread every 30 milliseconds
public void processData() {
final List<Map.Entry<String, Long>> entries = new ArrayList<>();
clientidToTimestampHolder.drainTo(entries);
for (Map.Entry<String, Long> entry : entries) {
String clientid = entry.getKey();
long timestamp = entry.getValue();
boolean isUpdated = isUpdatedClient(clientid, timestamp);
if (!isUpdated) {
updateClient(String.valueOf(clientid));
}
}
}
}
是我上面的代碼線程安全,沒有競爭條件?由於add
方法將從多個線程調用,然後我有一個後臺線程,每30毫秒運行一次,調用processData()
方法,該方法從clientidToTimestampHolder
提取數據LinkedBlockingQueue。
因爲現在看起來像在重負載下,我的processData()
方法可能會丟失幾個通過add
方法添加的條目。我在我的add
方法中添加了幾個日誌,其中打印出clientid
,但不知怎的,相同的clientid
沒有打印出我在isUpdatedClient
方法中添加的日誌,因此使它對我產生懷疑。
我與Java 7
如果你想在被調用的方法中檢查異常,或者你期望返回結果,那麼使用callable,否則你可以使用runnable – MohanaPriyan
@MohanaPriyan沒有返回結果,並且submit(Runnable)檢查異常的方式與提交(贖回)。所以提交(Runnable)是可以的。 –