Как реализовать действительно асинхронный поток Java - PullRequest
16 голосов
/ 20 апреля 2010

У меня есть функция, которая должна выполнить две операции: одну, которая быстро завершается, и другую, выполнение которой занимает много времени. Я хочу иметь возможность делегировать длительную операцию потоку, и мне все равно, когда поток завершится, но потоки должны быть завершены. Я реализовал это, как показано ниже, но моя вторая операция никогда не выполняется, когда функция завершается после вызова 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
 }
} 

Ответы [ 6 ]

40 голосов
/ 20 апреля 2010
public void someFunction(final String data) {
    shortOperation(data);
    new Thread(new Runnable() {
        public void run(){
            longOperation(data);
        }
    }).start();
}

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

  1. запущенная нить не помечена как демон (в приведенном выше коде это нет)
  2. longOperation() не выдает исключение и
  3. нет вызовов System.exit () в longOperation()
1 голос
/ 20 апреля 2010

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

1 голос
/ 20 апреля 2010

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

0 голосов
/ 19 апреля 2019

Возможно, уже поздно ответить на этот вопрос, но вот рабочее решение. Просто добавьте исполняемые файлы в 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
            }
        });
0 голосов
/ 21 декабря 2018

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

public void someFunction(String data) {
    smallOperation();
    new Thread(() -> {
        // doSomething long running
    }).start();
}
0 голосов
/ 14 августа 2017

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

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