私はMSプロジェクトの一環として、金融市場のデータディストリビューターアプリケーションを作成しています。アプリケーションはほぼ完成していますが、アプリは適切にスケーリングされていません。
これがその仕組みです。私は「偽の」取引所に加入して市場データを取得します。サブスクライブした後、最初のスナップショットを取得し、その後、デルタを継続的に受信します...
1) Subscribe for IBM.
2) Snapshot : Buy:50|Size:1400||Sell:49|Size:1000
(At buy price of 50, 1400 shares and at sell price of 49, 1000 shares available)
3) Update1: -1|10||-2|25
(Buy price is now 49 (50-1), buy Size is 1410. Sell price is 47 and sell size is 1025)
4) Update2 ...
.
.
.
市場データを処理するクラスが1つあります。以下のdataUpdate()は、「偽の」交換アプリケーションが1つのスレッドで呼び出すコールバックメソッドです。
class MarketDataProcessor:
Map<String, MarketData> marketDataMap = new HashMap<String, MarketData>(1000);
ConcurrentMap<String, MarketData> distMap = new ConcurrentHashMap<String, MarketData>();
//**Always called by one thread (MarketDataThread)**
public void dataUpdate( MarketDataUpdate dataUpdate ){
try{
//IBM
String symbol = dataUpdate .getSymbol();
MarketData data = marketDataMap.get( symbol );
if ( data = null ){
data = new MarketData( dataUpdate );
}else{
//Apply the delta here and save it ...
marketDataMap.put( symbol, data );
}
distMap.put( symbol, data );
}catch( Exception e ){
LOGGER.warn("Exception while processing market data.");
LOGGER.warn("Exception: {}", e);
}
}
取引所から市場データを取得した後、スレッドセーフな方法で配布する必要があります。これは、20以上のスレッドから呼び出される可能性があるため、拡張性が低く、原子性を確保するために外部ロックを使用するメソッドです。
public final double[] getData( String symbol, Side side ){
double[] dataArray = {0.0, 0.0};
synchronized( LOCK ){
MarketData data = distMap.get( symbol );
dataArray = ( side == BUY ) ? getBuyData(data) : getSellData(data);
}
return dataArray;
}
これが私の提案する解決策です。上記の方法を2つに分割することです。
//No external lock as it uses a ConcurrentHashMap
public final MarketData getData( String symbol ){
return distMap.get( symbol );
}
//State of this method is now confimed to the
//stack of the calling thread, therefore thread safe.
public final double[] getData( MarketData data, Side side ){
return ( side == BUY ) ? getBuyData(data) : getSellData(data);
}
これによりAPIが変更され、ユーザーが1つよりも2つのメソッドを呼び出せるようになることを認めると、外部ロックを使用せずにスレッドセーフになりませんか?
ありがとうございました。