Как реализовать реалистично асинхронный поток 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();