add
메서드가 여러 스레드에서 호출되어 clientidToTimestampHolder
LinkedBlockingQueue를 채우는 클래스가 있습니다. 그리고 나서 같은 클래스에서 나는 매 30 밀리 초마다 실행되는 백그라운드 스레드를 가지고 processData()
메서드를 호출하여 clientidToTimestampHolder
을 Map List에 배수 한 다음 적절한 메서드를 호출하여 다른 서비스에 데이터를 보내도록 List를 반복합니다.여러 스레드에서 메서드를 호출하여 데이터 구조를 채운 다음 단일 백그라운드 스레드에서 해당 데이터 구조를 읽을 수 있습니까?
타임 스탬프가 같은 여러 사용자 ID를 여러 번 얻을 수 있으므로 맵과 함께 LinkedBlockingQueue
을 사용하고 있습니다.
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));
}
}
}
}
내 위의 코드 스레드 안전한가요 거기에는 경쟁 조건이없는 내가 processData()
방법으로 데이터를 놓치지 않을 것입니다? add
메서드는 여러 스레드에서 호출되고 난 다음 LinkedBlockingQueue에서 데이터를 추출하는 processData()
메서드를 호출하기 위해 매 30 밀리 초마다 실행되는 단일 배경 스레드가 있습니다.
나는이 참고 문헌을 부적절하게 출판 했습니까? 어떻게 해결할 수 있을까요? 그래'String # valueOf' 내가 고칠거야. – user1234
생성자입니다. 안전하지 않은 게시를 방지하는 일반적인 방법은 정적 팩토리를 사용하고 생성 한 후에 예약 된 작업을 시작하는 것입니다. 즉, 'Handler newInstance() {Handler h = new Handler(); h.executorService.scheduleAtFixedRate (...); 귀환 h; }'를 호출하고 INSTANCE 홀더를 초기화하기 위해 팩토리를 사용하십시오. – xTrollxDudex