我正在开发一个股票交易应用程序,其关键功能是尽快(无阻塞)从另一个系统接受一些数据。我的应用程序将在稍后处理数据。
所以我的想法是让消息在 LinkedBlockingQueue/LinkedTransferQueue 中排队,然后定期排空队列并在后台线程中处理数据。
大致如下:
private final LinkedTransferQueue<Data> queue = new LinkedTransferQueue<Data>();
public void store( int index, long time, String[] data ) throws InterruptedException{
Data data = new Data( index, time, data );
queue.put( data );
}
private class BackgroundProcessor implements Runnable{
private List<Data> entryList = new LinkedList<Data>( );
@Override
public void run(){
try {
while ( keepProcessing ){
int count = queue.drainTo( entryList );
for ( Data data : entryList ){
//process data
}
}
} catch( Exception e ){
logger.error("Exception while processing data.", e);
}
}
}
然后我想测试这种方法的性能:
public void testStore( String[] dataArray ) throws InterruptedException{
int size = 100 * 1000;
long iTime = System.nanoTime();
for ( int i=0; i < size; i++ ){
store( i, System.nanoTime, dataArray );
}
long fTime = System.nanoTime();
System.err.println("Average Time (nanos): " + (fTime - iTime)/size;
float avgTimeInMicros = ((float) (fTime - iTime)/(size * 1000));
System.err.println("Average Time (micros): " + avgTimeInMicros);
}
我看到在我的 testStore() 中,如果 size = 100,0000,我可以创建 Data 对象(这是一个不可变的对象)并在 0.8 微秒内排队。但是,如果我将尺寸减小到 50,则需要多达 20 微秒。
我假设,一段时间后 jvm 会优化我的代码。 但是,在我的应用程序中,突发获取 50 条数据消息更为现实,有没有办法调整 jvm(或我的代码)以在 1-2 微秒内排队,而不管突发大小如何?
P.S 我在 jdk 1.6 上使用 -mx == -ms 512m 尝试了此测试。
最佳答案
处理 10,000 个,然后在 JVM 预热后测试 50 个突发。对于交易系统,您需要在开始交易之前确保 JVM 已预热。
如果您希望您的交易系统始终保持快速,您可以考虑如何在不丢弃任何对象的情况下完成它。
您可能会发现 Disruptor 库很有趣。它设计用于每秒处理 5 M 消息或更多。 http://code.google.com/p/disruptor/
关于java - LinkedBlockingQueue 中 put() 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8974082/