Является Future.get () заменой для Thread.join ()?

У меня не было возможности протестировать этот код, но общая идея состоит в том, чтобы перебрать дерево через цикл for-each над дочерними элементами. Мы сохраняем текущий путь внутри строки, добавляя текущее имя на каждом шаге рекурсии. Затем при попадании в лист мы добавляем текущий путь в список.

public ArrayList<String> buildListOfPaths(Node tree) {
    ArrayList<String> list = new ArrayList<String>();
    String str = "";
    traverse(tree, list, str);
    return list;
}

// The idea on how to iterate the elements comes from:
// https://stackoverflow.com/a/19338057
public void traverse(Node root, ArrayList<String> list, String str){ 
    // we know it's a leaf so we can add this path to the list
    if (root.getChildren() == null) {
        list.add(str + root.name);
        return;
    } else {
        for(Node each : root.getChildren()){
            traverse(each, list, str + each.name);
        }
    }
}

8
задан ashitaka 6 March 2009 в 03:15
поделиться

4 ответа

Да, способ, которым Вы записали их, эквивалентен.

Однако Вы не должны действительно ожидать потока Супердемона для завершения. Когда основной поток закончит выполняться основной (), тот поток выходы, но JVM не будет. JVM будет продолжать бежать, пока последний поток недемона не выходит из своего метода выполнения.

Например,

public class KeepRunning {
  public static void main(String[] args) {
    Superdaemon d = new Superdaemon();
    d.start();
    System.out.println(Thread.currentThread().getName() + ": leaving main()");
  }
}

class Superdaemon extends Thread {
  public void run() {
    System.out.println(Thread.currentThread().getName() + ": starting");
    try { Thread.sleep(2000); } catch(InterruptedException e) {}
    System.out.println(Thread.currentThread().getName() + ": completing");
  }
}

Вы будете видеть вывод:

main: leaving main()
Thread-0: starting
Thread-0: completing

Другими словами, основной поток приходит первым, затем вторичный поток завершается и выходы JVM.

12
ответ дан 5 December 2019 в 08:54
поделиться

Проблема - то, что книги как JCIP защищают это, мы используем Исполнителей для Потоков запусков. Таким образом, я стараюсь изо всех сил не использовать Thread.start (). Я не уверен, выбрал ли я обязательно конкретный способ сделать вещи только на основе простоты. Должна быть более убедительная причина, нет?

Убедительная причина использовать java.util.concurrent состоит в том, что многопоточное программирование очень хитро. Java предлагает инструменты тому (Потоки, синхронизируемые и энергозависимые ключевые слова), но это не означает, что можно безопасно использовать их непосредственно, не стреляя себе в ногу: Или слишком много синхронизации, приводящей к ненужным узким местам и мертвым блокировкам, или также меньше, приводя к ошибочному поведению из-за условий состязания).

С java.util.concurrent Вы получаете ряд утилит (записанный экспертами) для наиболее распространенных шаблонов использования, которые можно просто использовать, не волнуясь, что Вы разобрались в материале низкого уровня.

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

public static void main( String[] args )
{
    Runnable t = new Superdaemon();
    t.run();
}

Исполнители предназначены для задач, которые Вы хотите выполнить в фоновом режиме (когда у Вас есть несколько параллельных задач или когда Ваш текущий поток может продолжить делать что-то еще).

6
ответ дан 5 December 2019 в 08:54
поделиться

Future.get () получит будущий ответ от асинхронного вызова. Это также заблокируется, если вызов еще не был завершен. Это во многом как соединение потока.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html

1
ответ дан 5 December 2019 в 08:54
поделиться

Sort'a. Future.get() для того, чтобы иметь поток, уходят и вычисляют что-то и затем возвращают его вызывающему потоку безопасным способом. Это работало бы если get никогда не возвращался. Но, я придерживался бы с join звоните, поскольку это более просто и никакой Executer наверху (не, что было бы все так очень).

Править

Это похоже ExecutorService.submit(Runnable) предназначается, чтобы сделать exectly, чего Вы делаете попытку. Это просто возвращается null когда Runnable завершается. Интересный.

0
ответ дан 5 December 2019 в 08:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: