Helpers - компьютеры, интернет, программирование

Вызов метода из потока не завершается - Как завершить поток - Обходной путь

У меня есть следующий код.

ReadWriteLock someLock = new ReentrantReadWriteLock();
Condition someCondition = someLock.writeLock().newCondition();

public someMethod() {
    // do some stuff
    someCondition.await(); //Lock here.
    System.out.prinltn("This never prints");
}

public doSomeStuff() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                someMethod();
                System.out.println("thread finished");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread is going to die");
        }
    }).start();
}

Когда поток вызывает метод someMethod(), он выполняется. Но поскольку для этой функции есть метод await(). Он никогда не заканчивается / он не печатает «Это никогда не печатается», если только его не разбудит singnalAll(). Но я хочу, чтобы поток был завершен после его выполнения.

Я не могу реорганизовать все это. Мне просто нужно обходное решение этой проблемы. Он используется в приложении Swing. Так что нить важна.


  • для вызова метода должен быть связанный с ним поток, если вы хотите освободить и завершить текущий поток, вам придется создать другой поток и метод вызова в этом потоке 13.06.2014
  • @JigarJoshi хочешь уточнить? 13.06.2014
  • обновлено (с осторожностью :) ) 13.06.2014
  • вы можете использовать Condition#await(time,TimeUnit), которое заставляет текущий поток ожидать, пока он не получит сигнал или не будет прерван, или пока не истечет указанное время ожидания. 13.06.2014
  • @Braj, не имеет значения. 13.06.2014

Ответы:


1

Я думаю, это будет делать:

Thread thread =
  new Thread(new Runnable() {
    @Override
    public void run() {
        try {
          someMethod();
          System.out.println("thread finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread is going to die");
    }
  });

thread.start( );

final long reasonableTimeout = ...;

thread.join( reasonableTimeout );

// THIS WILL SHAKE IT UP
thread.interrupt( );

thread.join( );

// At this point, it is guaranteed that the thread has finished
12.06.2014
  • Хаки хммм! :-) Какой-нибудь чистый обходной путь, который вы можете придумать? 13.06.2014
  • @Kevin Ваши требования не чисты, так что это настолько чисто, насколько это возможно. Лично я бы переписал someMethod, но если это часть сторонней библиотеки, у вас может не быть выбора. 13.06.2014

  • 2

    Я не уверен, правильно ли я понял ваш вопрос, но я думаю, что вы хотите запустить функцию someMethod(), а затем заставить вызывающую программу выйти, не дожидаясь завершения someMethod(). Это означает, что вы в основном разветвляете свой поток выполнения на два: один, где работает someMethod(), ожидая своего надлежащего пробуждения, а другой, где вызывающий абонент просто продолжает (что ему нужно будет сделать, если вы хотите, чтобы он закончился) после вызова someMethod (). Для этого вам нужно будет запустить someMethod() в отдельном потоке. Что-то вроде этого.

    public doSomeStuff() {
        new Thread(new Runnable() {
            @Override
            public void run() {
            try {
                new Thread(){
                    public void run(){
                        someMethod();
                    }
                }.start();
                System.out.println("thread finished");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread is going to die");
        }
      }).start();
    }
    
    12.06.2014
  • Не на месте, не в уме? Теперь вместо одного потока у вас есть два, и проблема остается. 13.06.2014

  • 3

    Два способа разобраться в этом.

    1) Разработайте свою задачу с помощью политики прерывания

    Сделайте защитное кодирование. Если ваша задача каким-либо образом прерывается, программа должна знать, как с этим справиться.

    2) Добавьте POISON PILL, как в этом примере, Как только вы

    public someMethod() {
        while(condition predicate){
        someCondition.await(TIME_OUT); //Lock here.
    }
    //ADD Poison pill here
        System.out.prinltn("This never prints");
    }    
    

    Согласно параллелизму Java на практике

    При использовании условий ожидания (Object.wait или Condition.await):

    1) Всегда имейте условие, определяющее некоторую проверку состояния объекта, которая должна выполняться перед продолжением;

    2) Всегда проверяйте предикат условия перед вызовом ожидания и снова после выхода из ожидания;

    3) Всегда вызывайте ожидание в цикле;

    4) Убедитесь, что переменные состояния, составляющие предикат условия, защищены блокировкой, связанной с очередью условий;

    5) удерживать блокировку, связанную с очередью условий, при вызове wait, notify или notifyAll; а также

    6) Не снимать блокировку после проверки предиката условия, но перед действием на него.

    13.06.2014
    Новые материалы

    Интуитивное понимание тензоров в машинном обучении
    Тензор является важной концепцией во многих научных областях, таких как математика, физика, обработка сигналов и компьютерное зрение, и это лишь некоторые из них. В математике тензор — это..

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

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

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..