Creating callable threads as a daemon

How can I make the thread Callable as a daemon thread?

Here is what I am trying. I am trying to execute a set of threads, one of which does not terminate and goes into an infinite loop. What it does is the main flow of the program, which doesn't end even if all the instructions in the code are executed. The main thread then goes into suspended mode.

Here is a code snippet for the same.

public class MyThread implements Callable<String> {

    private int value;

    public MyThread(int value) {
        this.value = value;
    }

    @Override
    public String call() throws Exception {

        //Thread.currentThread().setDaemon(true);

        System.out.println("Executing - " + value);

        if (value == 4) {
            for (; ; );
        }

        return value + "";
    }
}

      

Main program

public class ExecutorMain {

    public static String testing() {    
        ExecutorService executor = null;
        List<Future<String>> result = null;
        String parsedValue = null;
        try {
            executor = Executors.newSingleThreadExecutor();

            List<MyThread> threads = new ArrayList<MyThread>();

            for (int i = 1; i < 10; i++) {
                MyThread obj = new MyThread(i);
                threads.add(obj);
            }

            result = executor.invokeAll(threads, Long.valueOf("4000"), TimeUnit.MILLISECONDS);
            //result = executor.invokeAll(threads);

            for (Future<String> f : result) {
                try {
                    parsedValue = f.get();
                    System.out.println("Return Value - " + parsedValue);
                } catch (CancellationException e) {
                    System.out.println("Cancelled");
                    parsedValue = "";
                    f.cancel(true);
                }
            }

            executor.shutdownNow();
        } catch (Exception e) {
            System.out.println("Exception while running threads");
            e.printStackTrace();
        } finally {
            List executedThreads = executor.shutdownNow();

            System.out.println(executedThreads);

            for (Object o : executedThreads) {
                System.out.println(o.getClass());
            }
        }
        System.out.println("Exiting....");
        //System.exit(1);

        return "";
    }

    public static void main(String[] args) {
        testing();
    }
}

      

What I realized from my previous question about Dangling threads in Java is that I need to make my threads as daemon threads.

+2


source to share


4 answers


You need to use a new ThreadFactory

one that creates daemon threads. See this answer here:

Executor and Daemon in Java

By default, executors create non-daemon threads whenever they create their pools. But you can enter your own ThreadFactory

, which creates threads for the pool.

For example:

executor = ExecutorService.newSingleThreadExecutor(new MyThreadFactory());

      

ThreadFactory

implements the method newThread

:



Thread newThread(Runnable r)

      

Copied from the answer linked to above, you can implement it like this:

class MyThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setDaemon(true);
        return thread;
    }
}

      

You mentioned in your question:

//Thread.currentThread () setDaemon (true) ;.

Yes it won't work because you cannot set the daemon flag after the thread has started.

+6


source


This is not about creating Callable

for a demon. You really want threads of execution to become daemons. You can create a thread so that it becomes a daemon:



executor = Executors.newSingleThreadExecutor(new ThreadFactory(){
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }        
});

      

+4


source


Just installing the Thread

daemon generated ExecutorService

for the daemon won't help (although you need it). You can set yours ExecutorService

Thread

for the daemon like this:

executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }        
});

      

The real problem you are having is with this block of code:

        for (Future<String> f : result) {
            try {
                parsedValue = f.get();
                System.out.println("Return Value - " + parsedValue);
            } catch (CancellationException e) {
                System.out.println("Cancelled");
                parsedValue = "";
                f.cancel(true);
            }
        }

        executor.shutdownNow();

      

In particular, this code will hang here forever:

parsedValue = f.get();

      

The reason for this is simple, the method Future#get

"Waits if necessary to complete the computation, and then retrieves its result", but the computation will never complete, because it is in an infinite loop. Even interrupting from ThreadPoolExecutor#shutdownNow

or Future#cancel(true)

will help you because your code is Callable

not executing a blocking function or otherwise checking for an interrupt.

Here you have two options:

  • Use a form Future#get

    that takes an argument long timeout

    .
  • Use Future#isDone

    to determine if the method has a Future#get

    return value before the actual call Future#get

    .
0


source


Thanks to Tim for the detailed explanation. However, the proposed solution did not solve the problem. The problem was that since the thread went into an infinite loop, it does not check for interruption of the thread and therefore does not exit.

For my scenario, an infinite loop is not a good example, but what we tried to accomplish is that we are executing a regex that took too long to execute, and the interrupt check was triggered by a call to matcher.find (), since find () does not return at the specified time. and also the find () method does not check for thread interruptions, we faced the issue of interrupted threads. Finally, implemented InterruptableCharSequence from this url and got it working.

0


source







All Articles