简体   繁体   English

这个Java应用程序如何在不扩展线程或实现可运行的情况下运行多个线程?

[英]How is this java app running multiple threads without extending threads or implementing runnable?

I'm learning Java and was able to do a bit of multi-threading with my existing apps using runnable. 我正在学习Java,并且能够使用runnable对我现有的应用程序进行一些多线程处理。 I was now looking at disruptor(to share variables between threads), but I can't figure out how the author is actually spawning threads. 我现在正在查看干扰器(在线程之间共享变量),但是我无法弄清楚作者实际上是如何生成线程的。

I see he is using Executor, which I use to submit runnable classes to in my program but in this example there is no submit(or runnable). 我看到他使用的是Executor,我用来在我的程序中提交可运行的类,但是在此示例中,没有Submit(或可运行)。 I only learned what I know from the Oracle tutorials and they mention the only two ways is to extend threads or implement runnable(I don't see either here, but he does submit executor to disruptor, which maybe how he's threading?). 我只是从Oracle教程中学到了知识,他们提到了仅有的两种方法是扩展线程或实现可运行(我在这里什么都看不到,但是他确实将执行器提交给了干扰者,也许他是如何进行线程处理的?)。 Am I missing something or is this person doing it in a different way? 我是否缺少某些东西,或者这个人以不同的方式来做? My end goal is to understand this code(which works perfectly) so I can apply it to my existing (using runnable) code. 我的最终目标是理解此代码(效果很好),因此我可以将其应用于现有(使用可运行的)代码。

Here's the code in question: 这是有问题的代码:

App.java 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);
    }
}

Update: if Disruptor is handling the spawning of threads then how can I submit my existing runnable class to it? 更新:如果Disruptor正在处理线程的产生,那么如何向其提交现有的可运行类? or do I need to rework the code again? 还是我需要再次修改代码? Sorry I'm a bit confused on if disruptor is going to work with existing code or if I need to completely change my stuff for it. 抱歉,如果中断器要与现有代码一起使用,或者是否需要对其进行完全更改,我有点困惑。

As you suspect, the actual dealing with threads (via submitting work items) is done inside Disruptor . 您怀疑,实际的线程处理(通过提交工作项)是在Disruptor完成的。 So you need to look at its source code (to your luck, it is open source), to find this: 因此,您需要查看其源代码 (幸运的是,它是开源的)才能找到此代码:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM