0

I have a consumer/producer program where:

  • items to be processed (Strings) go into a BlockingQueue
  • I instantiate a fixed number of threads that perform take() from that BlockingQueue and then process those Strings.

The processing threads are instances of this class:

class ProcessingThread extends Thread {

    private void process(String s) {
        (big method with calls to other big methods)
    }

    public void run() {
        String s = queue.take();
        process(s);
    }
}

Converting to an Executor would be quite straightforward: the Strings would go straight into the Executor, along with a Runnable:

class Task implements Runnable {

     private void process(String s) {
        (big method with calls to other big methods)
    }

    public void run() {
         process(s);
     }

}

and then:

executor.execute(new Task(s));

But...every time I instantiate a Task, it would instantiate a very large chunk of code (the processor) - I can't have that, memory requirements would go sky high.

How do I do this?

Piero dS
  • 153
  • 1
  • 1
  • 5
  • 2
    "*it would instantiate a very large chunk of code*" => what do you mean? – assylias Oct 20 '15 at 16:23
  • 3
    What do you mean by "instantiate a very large chunk of code"? All instances share the same code. It's not like the byte code of each method is copied every time you instantiate an object. – aioobe Oct 20 '15 at 16:23
  • I mean that the class ProcessingThread is big, and the resulting Runnable would also be big and expensive to instantiate. – Piero dS Oct 20 '15 at 16:26
  • Don't worry about that yet. Most likely it's not even an issue. I think this is a case of pre-mature optimization. And you are probably talking about measly milliseconds for instanciation. – Damien O'Reilly Oct 20 '15 at 16:31
  • I currently have 50 threads handling a million requests per hour. I KNOW I would get an OutOfMemoryError. – Piero dS Oct 20 '15 at 16:36
  • 1
    Then you need to allocate your VM heap accordingly. Or scale horizontally and/or vertically if required. But just so you know, instantiating a class multiple times, does not result in multiple copies of said classes bytecode. – Damien O'Reilly Oct 20 '15 at 16:43
  • To put some figures into perspective, 1,000,000 requests an hour is not really large today. Its 16,666 a minute. 277 a second. If you have 50 threads, then 20,000 per thread per hour, 333 per thread per minute, and 5 per thread per second. I think you should go with your solution above, profile the application with the workload, and look for any red spots. – Damien O'Reilly Oct 20 '15 at 16:45
  • Well, yes and no. I can surely do these things, but to me it's much more elegant to have a way to customize how threads are created by the executor. – Piero dS Oct 20 '15 at 17:00
  • I guess I'm not following. Customize in what way ? The concurrency package in the JDK is huge, and you can do almost anything really: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html – Damien O'Reilly Oct 20 '15 at 17:05
  • 1
    Re, "customize how threads are created by the executor." That's what a `ThreadFactory` is for. Two of the constructors for the `ThreadPoolExcecutor` class accept a `ThreadFactory` instance as an argument. Supply your own implementation of `ThreadFactory`, and you will have full control of how the threads are created. – Solomon Slow Oct 20 '15 at 20:03
  • 1
    What you already done is a specialized executor service. Are you sure you want to switch to a standard implementation? What do you want to achieve by that? – Alexei Kaigorodov Oct 21 '15 at 16:01
  • 1
    How do you do this? Well to begin with use Runnable. It is the recommended way because it decouples task body from task execution. You are not supposed to extend Thread these days. In fact your thread approach is worse from the memory point of view, as instances of Thread have more variables than instances of Runnable. With Runnables you can have a fixed number of threads. – Mister Smith Oct 29 '15 at 19:57

1 Answers1

0

I ended up taking Damien O'Reilly advice.

Then you need to allocate your VM heap accordingly. Or scale horizontally and/or vertically if required. But just so you know, instantiating a class multiple times, does not result in multiple copies of said classes bytecode. – Damien O'Reilly Oct 20 at 16:43

Piero dS
  • 153
  • 1
  • 1
  • 5