I는 트랜잭션을 관리 할 수 있도록 나에게 의미가 있습니다 데이터베이스의 두 번째 Telcontar's suggestion인데 실제로는이 규모의 데이터를 관리하고 스레드 간 협상을 위해 설계 되었기 때문에 인 메모리 콜렉션은 그렇지 않습니다.
데이터가 서버의 데이터베이스에 있다고 말하면 클라이언트의 로컬 목록은 사용자 인터페이스를위한 것입니다. 한 번에 클라이언트에있는 모든 100000 항목을 유지하거나 복잡한 편집을 수행 할 필요는 없습니다. 클라이언트에서 원하는 것은 데이터베이스에 대한 간단한 캐시입니다.
데이터의 현재 하위 집합 만 클라이언트에 한 번에 저장하는 캐시를 작성하십시오. 이 클라이언트 캐시는 자체 데이터에 대해 복잡한 다중 스레드 편집을 수행하지 않습니다. 대신 모든 편집 내용을 서버에 제공하고 업데이트를 수신합니다. 서버에서 데이터가 변경되면 클라이언트는 단순히 오래된 데이터를 잊어 버리고 다시로드합니다. 하나의 지정된 스레드 만이 콜렉션 자체를 읽거나 쓸 수 있습니다. 이 방법으로 클라이언트는 복잡한 편집 자체가 필요하지 않고 서버에서 발생하는 편집 내용을 그대로 반영합니다.
네, 상당히 복잡한 해결책입니다. 그것의 구성 요소는 다음과 같습니다
이 아니라 모든 일
- 변경된 데이터
- 캐시 클래스에 대한 업데이트를 수신하기위한 프로토콜보다, 항목 478712-478901를 데이터의 범위를로드하기위한 프로토콜 말할
- 서버에 알려진 인덱스로 항목을 저장하는 서버
- 서버와 통신하는 해당 캐시에 속한 스레드. 이는 수집 자체에 기록하는 전용 스레드
- 데이터
- 이로드되었을 때 UI 구성 요소들이 데이터를주고받을 수 있도록 구현되는 인터페이스를 검색 할 때 콜백을 처리하도록 캐시에 속하는 스레드
첫째 자상에서
이 캐시의 뼈는 다음과 같이 보일 수 있습니다 : 당신은 분명, 자신을 위해 기입해야합니다 세부 사항이 많이있다
class ServerCacheViewThingy {
private static final int ACCEPTABLE_SIZE = 500;
private int viewStart, viewLength;
final Map<Integer, Record> items
= new HashMap<Integer, Record>(1000);
final ConcurrentLinkedQueue<Callback> callbackQueue
= new ConcurrentLinkedQueue<Callback>();
public void getRecords (int start, int length, ViewReciever reciever) {
// remember the current view, to prevent records within
// this view from being accidentally pruned.
viewStart = start;
viewLenght = length;
// if the selected area is not already loaded, send a request
// to load that area
if (!rangeLoaded(start, length))
addLoadRequest(start, length);
// add the reciever to the queue, so it will be processed
// when the data has arrived
if (reciever != null)
callbackQueue.add(new Callback(start, length, reciever));
}
class Callback {
int start;
int length;
ViewReciever reciever;
...
}
class EditorThread extends Thread {
private void prune() {
if (items.size() <= ACCEPTABLE_SIZE)
return;
for (Map.Entry<Integer, Record> entry : items.entrySet()) {
int position = entry.key();
// if the position is outside the current view,
// remove that item from the cache
...
}
}
private void markDirty (int from) { ... }
....
}
class CallbackThread extends Thread {
public void notifyCallback (Callback callback);
private void processCallback (Callback) {
readRecords
}
}
}
interface ViewReciever {
void recieveData (int viewStart, Record[] records);
void recieveTimeout();
}
.
import java.util.Collections;
import java.util.ArrayList;
ArrayList list = new ArrayList();
List syncList = Collections.synchronizedList(list);
// make sure you only use syncList for your future calls...
이 쉬운 솔루션입니다 :
나는 ConcurrentSkipListMap 아이디어를 좋아합니다. 90 %의 시간에 목록은 일부 타임 스탬프 (각 도메인 객체의 ID의 일부)에 따라 정렬되므로,이를 최적화하는 것이 좋습니다. 나머지 10 %는 여전히 생각할 것입니다. –