18

I am just curious on how people solve this. I often write the same type of code all the time. For instance:

new Thread() {
   //...
   //...
   //...
   //Change this line
   //...
   //...
}.start();

I keep changing the line where it says "Change this line" and then starting a thread. This change can be one line or a few lines. How would I go about compacting this code?

Legend
  • 113,822
  • 119
  • 272
  • 400
  • 3
    It is not at all an answer to your question but it is generally considered more correct to implement a Runnable than extending Thread. The reason is simply that it is not really the Threads behavior you want to change (which is to run a Runnable) but what it runs. – Fredrik Nov 13 '09 at 22:45

7 Answers7

21

Well, I guess you could run your java files through the C preprocessor...

gnud
  • 77,584
  • 5
  • 64
  • 78
18

You can use the template pattern to create a base class that contains the common code. For example:

public abstract class ThreadTemplate extends Thread
{

    public void run() {
        //reusable stuff
        doInThread();
        //more resusable stuff
    }

    abstract void doInThread();

}

Then starting a thread with the boilerplate code is as easy as:

new ThreadTemplate{
   void doInThread() {
       // do something
   }
}.start();

Also, a less elegant solution to save yourself some typing is to use the templating feature of your ide. You can find some info on setting them up in Eclipse here and you can find a list of useful ones at Useful Eclipse Java Code Templates

Community
  • 1
  • 1
Jason Gritman
  • 5,251
  • 4
  • 30
  • 38
  • Not sure why you're getting modded down, this is the _exact_ right answer if, from what he says, those //... lines are common. – Nick Veys Nov 13 '09 at 23:13
  • Wasn't the idea to _compact_ the code, not make it longer? – Sotanaht Mar 18 '14 at 22:01
  • @Sotanaht By "compact the code", the OP meant to implement the DRY principle. Yes, the base class is a little longer, but now whenever he has to write another thread, it's only 4 lines of boiler plate plus the unique code. If the general behavior is large, that quickly adds up to fewer lines typed. – Cody Poll Mar 31 '14 at 17:14
8

One technique is to put the code in an anonymous inner class, and pass that to a method that does the rest.

interface SomeInterface {
    void fn();
}

    executeTask(new SomeInterface {
        public void fn() {
            // Change this line.
        }
    });

private void executeTask(final SomeInterface thing) {
     Thread thread = new Thread(new Runnable() { public void run() {
        //...
        //...
        //...
        thing.fn();
        //...
        //...
     }});
     thread.start();
}

Generally it isn't a good idea to extend Thread or other classes if it is unnecessary.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
7

It's possible to use Java annotations to generate boilerplate code. Writing your own annotation processor is not hard.

djna
  • 54,992
  • 14
  • 74
  • 117
1

If it is something that you use in many projects, I would set this up in your IDE. For instance I use eclipse and if you go to Window->Preferences->Java->Editor->Templates you can setup your own templates, and then have them auto complete. For instance I always start typing sysout and then press tab, and eclipse has a built in template to replace that with System.out.println();

There are many pre-built templates in eclipse, so you could look at those for examples on syntax, if that is the IDE you use, if not there may be something similiar in other IDE's

This is very useful, and you could create one for any boiler code you find yourself writing a lot.

broschb
  • 4,976
  • 4
  • 35
  • 52
0

Nope, no macros. For this case, the closest you can get is to create new Runnable instance and pass it to either a function of your own creation or an ExecutorService, which will start the task for you.

With Java, there's no good way to get rid of this "boilerplate" code, mainly because you can't pass pointers to functions; everything needs to be an object.

Tim Frey
  • 9,901
  • 9
  • 44
  • 60
0

In the case of a Thread, you can pass any object that implements Runnable to its constructor.

So, the solution is to create your own class:

public class MyClass implements Runnable {
    void run() {
        // change this line
    }
}

Unfortunately, run isn't static, so you'll have to create an instance of MyClass first:

new Thread(new MyClass()).start();

You could also add variables to MyClass and a constructor so you can pass arguments to it.

Edit: If you need more than just the start method, you can also subclass Thread itself.

Powerlord
  • 87,612
  • 17
  • 125
  • 175