Создание вызываемых нитей в качестве демона

Как я могу сделать вызываемую нить как нить демона?

Вот что я пытаюсь Я пытаюсь выполнить набор потоков, один из которых не завершается и идет в бесконечный цикл. Что он делает, так это основной поток программы, который не завершается, даже если все операторы кода выполняются. После этого основной поток переходит в режим ожидания.

Вот фрагмент кода для того же.

<code>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 + "";
    }
}
</code>

Основная программа

<code>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();
    }
}
</code>

Что я понял из моего предыдущего вопроса оВисячие темы в Java в том, что я должен делать свои темы как потоки демонов.

Ответы на вопрос(4)

Просто настройкаThreadс созданнымExecutorService чтобы демон не помог (хотя вам нужно это сделать). Вы можете установить свойExecutorService Threadс демоном вот так:

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

Настоящая проблема, с которой вы столкнулись, связана с этим блоком кода:

        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();

Более конкретно, этот код будет висеть здесь всегда:

parsedValue = f.get();

Причина этого проста,Future#get метод "Ожидает, если необходимо, чтобы вычисление завершилось, а затем извлекает его результат", но вычисление никогда не завершится, поскольку оно находится в бесконечном цикле. Даже не прерывание отThreadPoolExecutor#shutdownNow или жеFuture#cancel(true) поможет вам, потому что вашCallable код не выполняет блокирующую операцию или иным образом не проверяет прерывание.

Отсюда у вас есть два варианта:

Use the form of Future#get that takes a long timeout argument. Use Future#isDone to determine if the Future#get method has a value to return prior to actually calling Future#get.
 divinedragon06 апр. 2012 г., 15:12
Спасибо Тим за подробное объяснение. Однако предложенное вами решение не решило проблему. Проблема заключалась в том, что поскольку поток перешел в бесконечный цикл, он не проверяет прерывание потока и, следовательно, не прерывается.
 06 апр. 2012 г., 18:09
Право ,,, что не является проблемой, если это демон, и вы не блокируете поток, не являющийся демоном, ожидающий его завершения. Я упомянул проблему с не проверкой на прерывание. В любом случае, я рад, что вы поняли это. Этот материал важен! :-)

Это не о созданииCallable демону. Вы действительно хотите, чтобы потоки выполнения стали демонами. Вы можете создать поток следующим образом, чтобы он стал демоном:

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

Спасибо Тим за подробное объяснение. Однако предложенное вами решение не решило проблему. Проблема заключалась в том, что поскольку поток перешел в бесконечный цикл, он не проверяет прерывание потока и, следовательно, не прерывается.

Для моего сценария бесконечный цикл не является хорошим примером, но мы пытались выполнить то, что мы выполняли регулярное выражение, выполнение которого занимало слишком много времени, а проверка на прерывание выполнялась после вызова matcher.find (). Поскольку find () не возвращается в указанное время, а также метод find () не проверяет прерывания потока, мы столкнулись с проблемой зависания потока. Наконец, реализован InterruptableCharSequence изэтот URL и получил это работает.

 09 авг. 2015 г., 19:02
Вы добавляете посторонние неопубликованные данныеafter the fact, Некоторые из других ответов адресованы ФП правильно. Вместо того, чтобы создавать новый ответ, возможно, добавьте это как обновление к OP. В конце концов - причина, по которой решение Тима не удалось решить. проблема в том, что ваша & quot; проблема & quot; не соответствует описанию OP. Это неправильная формулировка ФП - но это не умаляет правильностиhis ответ.
Решение Вопроса

How can I make Callable thread as daemon thread?

Вам нужно использовать новыйThreadFactory это создает потоки демона. Смотрите этот ответ здесь:Исполнитель и Демон в Java

По умолчанию исполнители создают потоки, не являющиеся демонами, при создании своих пулов. Но вы можете ввести свой собственныйThreadFactory который создает потоки для пула.

Например:

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

ThreadFactory реализуетnewThread метод:

Thread newThread(Runnable r)

Скопированный из ответа, на который я ссылался выше, вы можете реализовать его следующим образом:

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

Вы упомянули в своем вопросе:

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

Да, это не сработает, потому что вы не можете установить флаг демона после запуска потока.

 05 апр. 2012 г., 16:58
Странно - у нас только что была небольшая дискуссия о дефолтах. Такого рода вещи случаются, когда функциональностью по умолчанию для закрытия приложения является «не». :)

Ваш ответ на вопрос