2

私は Java を学んでおり、runnable を使用して既存のアプリで少しマルチスレッドを実行することができました。(スレッド間で変数を共有するために)ディスラプターを見ていましたが、作成者が実際にどのようにスレッドを生成しているのかわかりません。

彼は実行可能なクラスをプログラムに送信するために使用するエグゼキューターを使用しているようですが、この例では送信(または実行可能)はありません。私はOracleのチュートリアルから知っていることだけを学びました.2つの方法は、スレッドを拡張するか、実行可能を実装することです. 私は何かを見逃していますか、それともこの人は別の方法でそれをやっていますか? 私の最終的な目標は、このコード (完全に機能する) を理解し、既存の (実行可能なコードを使用して) コードに適用できるようにすることです。

問題のコードは次のとおりです。

App.java

import com.lmax.disruptor.*;
import com.lmax.disruptor.dsl.*;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class App {

    private final static int RING_SIZE = 1024 * 8;

    private static long handleCount = 0;

    private final static long ITERATIONS = 1000L * 1000L * 300L;
    private final static int NUM_EVENT_PROCESSORS = 8;

    private final static EventHandler<ValueEvent> handler =
        new EventHandler<ValueEvent>() {
        public void onEvent(final ValueEvent event,
                                final long sequence,
                                final boolean endOfBatch) throws Exception {
        handleCount++;
    }
    };

    public static void main(String[] args) {
    System.out.println("Starting disruptor app.");

    ExecutorService executor = Executors.newFixedThreadPool(NUM_EVENT_PROCESSORS);

    Disruptor<ValueEvent> disruptor =
        new Disruptor<ValueEvent>(ValueEvent.EVENT_FACTORY, executor,
            new SingleThreadedClaimStrategy(RING_SIZE),
            new SleepingWaitStrategy());
    disruptor.handleEventsWith(handler);
    RingBuffer<ValueEvent> ringBuffer = disruptor.start();

    long start = System.currentTimeMillis();

        long sequence;
        ValueEvent event;
    for (long x=0; x<ITERATIONS; x++) {
        sequence = ringBuffer.next();
        event = ringBuffer.get(sequence);
        event.setValue(x);
        ringBuffer.publish(sequence);
        }
    final long expectedSequence = ringBuffer.getCursor();

    while (handleCount < expectedSequence) { }

    long opsPerSecond = (ITERATIONS * 1000L) / (System.currentTimeMillis() - start);
    System.out.printf("op/s: %d, handled: %d", opsPerSecond, handleCount);
    }
}

更新: ディスラプターがスレッドのスポーンを処理している場合、既存の実行可能なクラスをディスラプターに送信するにはどうすればよいですか? または、コードをもう一度作り直す必要がありますか? 申し訳ありませんが、ディスラプターが既存のコードで動作するのか、それとも自分のものを完全に変更する必要があるのか​​ について少し混乱しています.

4

1 に答える 1

7

ご想像のとおり、スレッドの実際の処理 (作業項目の送信による) は 内で行われDisruptorます。したがって、これを見つけるには、そのソース コードを確認する必要があります(幸運なことに、これはオープン ソースです)。

public RingBuffer<T> start()
{
    EventProcessor[] gatingProcessors = eventProcessorRepository.getLastEventProcessorsInChain();
    ringBuffer.setGatingSequences(Util.getSequencesFor(gatingProcessors));

    checkOnlyStartedOnce();
    for (EventProcessorInfo<T> eventProcessorInfo : eventProcessorRepository)
    {
        executor.execute(eventProcessorInfo.getEventProcessor());
    }

    return ringBuffer;
}
于 2012-03-13T17:20:58.687 に答える