11

I have a MyThread object which I instantiate when my app is loaded through the server, I mark it as a Daemon thread and then call start() on it. The thread is meant to sit and wait for information from a queue as long as the application is active. My problem/question is this: Currently MyThread is extending Thread because I mark it as Daemon and I read about how it's more prefferable to implement Runnable and to use Executors. So what I wanted to ask is if MyThread will implement Runnable instead of extending Thread (and of course will be renamed) and I'll use newSingleThreadScheduledExecutor() how, what or maybe where, do I mark something as Daemon. I hope I haven't made a mess of terms, please excuse me if I have as some parts of the multithreading environment are very new to me.

Thanks Ittai

Update: The module I'm referring to in my app is a web-app which has a few threads actually of this sort and what they do have in common is that they all in the ServletContext as a member for various reasons. Currently I extend Thread to WebThread which has the ServletContext as a memebr and all subclasses can utilize this. If I switch over to the Runnable paradigm with the Executor and ThreadFactory than basically I need to have an ugly hybrid of WebRunnable which implements Runnable and has the ServletContext as a public member and have my ThreadFactory implement newThread(WebRunnable arg0) in addition to newThread(Runnable arg0). I'm not sure what's best. Thanks

Ittai
  • 5,625
  • 14
  • 60
  • 97

3 Answers3

24

Check out the JavaDoc for newSingleThreadScheduledExecutor(ThreadFactory threadFactory)

It would be implemented something like this:

public class MyClass { 
    private DaemonThreadFactory dtf = new DaemonThreadFactory();
    private ScheduledExecutorService executor = 
                                 Executors.newSingleThreadScheduledExecutor(dtf);
    // ....class stuff.....
    // ....Instance the runnable.....
    // ....submit() to executor....
}

class DaemonThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setDaemon(true);
        return thread;
    }
}
Stu Thompson
  • 38,370
  • 19
  • 110
  • 156
  • Hi Stu, first of all thanks for your detailed answer but I'm not sure you saw my update? I updated the question with the fact that I need my `Threads/Runnables` to have an object of `ServletContext` when run is performed and I'm wondering how this can be acocmplished with Runnable. I know that with inheritance of `Thread` then it's no problem to plug it in the `ThreadFactory` but I'm not sure if or how it's possible with the Runnable paradigm. – Ittai Oct 04 '09 at 20:24
  • Ah, no, I didn't :P *(I opened up your question for answering but took my time getting to it.)* Let me think that through a bit and check out the other answer... – Stu Thompson Oct 07 '09 at 08:13
  • What I decided to do (can be changed though) is to have a `singleton` class which has a `commonResourcesMap` which will be `` and it will serve as that common resource for servlets and non-servlets. That way I can implement `Runnable` without a problem. – Ittai Oct 07 '09 at 11:36
  • 4
    I am certain there will be millions of DaemonThreadFactory classes created around the world, just because Executors doesn't provide a way to use deamon threads. – lenkite Apr 05 '11 at 12:03
12

If you're using a scheduled executor, you can provide a ThreadFactory. This is used to create new Threads, and you can modify these (e.g. make them daemon) as you require.

EDIT: To answer your update, your ThreadFactory just needs to implement newThread(Runnable r) since your WebRunnable is a Runnable. So no real extra work.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • +1 for technical correctness - but is there any advantage in using Executor in this context? Seems a little bit of "complexity for complexity's sake" for me (but maybe I'm wrong on this...) – hjhill Oct 04 '09 at 11:55
  • Perhaps not. But I've written systems before which use a single thread executor to begin with, and plugged in different executors at a later stage. – Brian Agnew Oct 04 '09 at 12:06
  • @Brian- I'm kind of thinking what hjhill is thinking. I have one thread as such and I'm not sure if it's worth my trouble utilizing the ThreadFactory – Ittai Oct 04 '09 at 15:36
  • @Brian again- After looking at things once over your solution is interesting if somewhat robust but I've updated the question so I'd be grateful if you could take another look and help me out – Ittai Oct 04 '09 at 16:13
  • My `WebRunnable` is a `Runnable` but in order for the `ThreadFactory` to be able to set the `ServletContext` member in the `WebRunnable` it needs to implement `newThread(WebRunnable r)` as `Runnable` does not have the setServletContext() method defined. Plus I have a public member (the ServletContext member) exposed on the WebRunnable interface. My question is if when you need a member for this group of Runnable/Thread isn't it wiser to use inheritance? I'm really not sure – Ittai Oct 04 '09 at 19:33
  • newThread(Runnable r) may have to check that you're passing in the correct Runnable type via "instanceof" and perform further work if need be. But I don't think that's the newThread() method's job. It's just there to create a thread, not manipulate a Runnable – Brian Agnew Oct 04 '09 at 22:29
2

Just to complement with another possible solution for completeness. It may not be as nice though.

final Executor executor = Executors.newSingleThreadExecutor();
Runtime.getRuntime().addShutdownHook(new Thread() {

    @Override
    public void run() {
        executor.shutdownNow();
    }
});
Johan Sjöberg
  • 47,929
  • 21
  • 130
  • 148