У меня есть класс ниже, в котором метод add
будет вызываться несколькими потоками для заполнения channelMessageHolder
CHM потокобезопасным способом.
В том же классе у меня есть фоновый поток, который запускается каждые 30 секунд и вызывает метод send
, передавая данные из channelMessageHolder
.
public class Processor {
private final ScheduledExecutorService executorService = Executors
.newSingleThreadScheduledExecutor();
private final AtomicReference<ConcurrentHashMap<Channel, ConcurrentLinkedQueue<Message>>> channelMessageHolder =
new AtomicReference<>(new ConcurrentHashMap<Channel, ConcurrentLinkedQueue<Message>>());
private Processor() {
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
send();
}
}, 0, 30, TimeUnit.SECONDS);
}
// this will be called by only single background thread
private void send(ConcurrentHashMap<Channel, ConcurrentLinkedQueue<Message>> messageByChannels) {
for(Entry<Channel, ConcurrentLinkedQueue<Message>> entry : messageByChannels.entrySet()) {
Channel channel = entry.getKey();
ConcurrentLinkedQueue<Message> messageHolder = entry.getValue();
while (!messageHolder.isEmpty()) {
Message message = messageHolder.poll();
....
// process this and send to database
}
}
}
// called by multiple threads
public void add(final Channel channel, final Message message) {
// populate channelMessageHolder in a thread safe way
}
}
Вопрос
Как вы можете видеть, channelMessageHolder
уже присутствует в моем классе Processor
, поэтому мне нужно явно передавать данные из этой карты каждые 30 секунд для отправки метода? Или я могу напрямую использовать его в своем методе отправки?
Путаница заключается в том, что если я напрямую использую его в своем методе отправки, то он будет заполняться несколькими потоками одновременно, поэтому я использую метод getAndSet
AtomicReference, чтобы передать его методу send
.
Дайте мне знать, если то, что я делаю, неправильно, и есть ли лучший способ сделать это?