Как реализовать реалистично асинхронный поток java

У меня есть функция, которая должна выполнять две операции: одну, которая заканчивается быстро, и одна из них занимает много времени. Я хочу иметь возможность делегировать длительную операцию в поток, и я не забочусь о завершении потока, но потоки должны быть завершены. Я реализовал это, как показано ниже, но моя вторая операция никогда не выполняется, так как функция выходит после вызова start(). Как я могу гарантировать, что функция вернется, но второй рабочий поток также завершит ее выполнение и не зависит от родительского потока?

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 

Ответы

Ответ 1

public void someFunction(final String data) {
    shortOperation(data);
    new Thread(new Runnable() {
        public void run(){
            longOperation(data);
        }
    }).start();
}

Если вызывается someFunction, JVM будет запускать longOperation, если

  • поток, выполняющий его, не отмечен как демон (в приведенном выше коде это нет)
  • longOperation() не генерирует исключение и
  • никаких вызовов в System.exit() не производится в longOperation()

Ответ 2

JVM не выйдет, пока поток не завершится. Этот код, который вы опубликовали, даже не компилируется; возможно, проблема в вашем фактическом коде.

Ответ 3

Если ваша вторая функция не выполняется, это не имеет никакого отношения к возврату вашей функции. Если что-то вызывает System.exit() или если ваша функция генерирует исключение, то поток остановится. В противном случае он будет работать до тех пор, пока он не будет завершен, даже если ваш основной поток остановится. Этого можно предотвратить, установив новый поток в качестве демона, но вы этого не делаете.

Ответ 4

Решение с использованием современной Java

public void someFunction(String data) {
    smallOperation();
    new Thread(() -> {
        // doSomething long running
    }).start();
}

Ответ 5

Возможно, уже поздно ответить на этот вопрос, но вот рабочее решение. Просто добавьте исполняемые файлы в ExecutorService.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

ExecutorService executor = Executors.newFixedThreadPool(10);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                //your code
            }
        });

Ответ 6

если я правильно понял ваш вопрос, вы хотите вызвать someFunction(), выполнить короткий smallOperation(), запустить поток к SecondOperation и убедиться, что при возврате из этой функции SecondOperation завершен.

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

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
   th.join(); //add this line to make your MainThread await for this to finish . 
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 

взгляните на эту статью, там говорится, что "когда мы вызываем метод join() для потока, вызывающий поток переходит в состояние ожидания. Он остается в состоянии ожидания до тех пор, пока на него не ссылаются" поток заканчивается ". что я думаю, что вы пытаетесь достичь

Если это не так, и вы хотите получать уведомления, когда SecondOperation завершает работу, я предлагаю вам использовать asyncTask

Ответ 7

Вы создаете настоящий асинхронный поток, создавая второй поток во временном потоке.

(new Thread(new Runnable() { public void run() {
    (new Thread(new Runnable() { public void run()
    {
        /* async thread */
    }})).start();
}})).start();