【问题标题】:How does one implement a truly asynchronous java thread如何实现一个真正的异步java线程
【发布时间】:2011-02-10 05:25:12
【问题描述】:

我有一个函数需要执行两项操作,一项完成速度很快,一项需要很长时间才能运行。我希望能够将长时间运行的操作委托给一个线程,我不在乎线程何时完成,但线程需要完成。我实现了这个,如下所示,但是,我的第二个操作永远不会完成,因为函数在 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
 }
} 

【问题讨论】:

  • 你从来没有在你的someFunction()中使用SecondOperation,你希望它如何运行?
  • 你甚至少了一个分号 :-/
  • 抱歉,修复了我的代码中的错误。

标签: java multithreading asynchronous runnable


【解决方案1】:
public void someFunction(final String data) {
    shortOperation(data);
    new Thread(new Runnable() {
        public void run(){
            longOperation(data);
        }
    }).start();
}

如果someFunction被调用,JVM会运行longOperation if

  1. 运行它的线程未标记 作为一个守护进程(在上面的代码中 不是)
  2. longOperation() 不会抛出异常并且
  3. longOperation() 中没有调用 System.exit()

【讨论】:

    【解决方案2】:

    JVM 不会在线程终止之前退出。您发布的这段代码甚至无法编译;也许问题出在您的实际代码中。

    【讨论】:

    • 我不知道您所说的“逻辑部分”是什么意思,但您提供的代码并不是导致线程终止的部分。
    【解决方案3】:

    如果您的第二个功能没有完成,则与您的功能返回无关。如果有东西调用System.exit() 或者你的函数抛出异常,那么线程将停止。否则,即使您的主线程停止,它也会一直运行直到完成。可以通过将新线程设置为守护进程来防止这种情况发生,但您在这里没有这样做。

    【讨论】:

    • 明确一点,如果没有其他非守护线程正在运行,将其设置为守护进程将导致 JVM 在完成之前退出。所以这与你想要的相反。您可以通过在 调用 start() 之前调用 Thread 对象上的 setDaemon(true) 来设置它。
    【解决方案4】:

    回答这个问题可能为时已晚,但这是可行的解决方案。 只需将 runnables 添加到 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
                }
            });
    

    【讨论】:

      【解决方案5】:

      从 Java 1.8 开始,您可以非常简单地运行异步代码。下个代码见:

      import java.util.concurrent.CompletableFuture;
      import java.util.concurrent.Semaphore;
      
      public class HelloWorld {
        public static void main(String[] args) {
          CompletableFuture<String> future = CompletableFuture.supplyAsync(()->
            //run the code async        
            "result"
          );
          String result = future.join(); //wait async result
          System.out.println(result);
        }
      }
      

      【讨论】:

        【解决方案6】:

        使用现代 Java的解决方案

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

        【讨论】:

          【解决方案7】:

          如果我的问题正确,你想调用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
           }
          } 
          

          看看这个article,它声明“当我们在线程上调用join()方法时,调用线程进入等待状态。它保持等待状态,直到被引用的线程终止”。我认为你想要完成的事情

          如果不是这样,并且您想在SecondOperation 终止时收到通知,我建议您使用asyncTask

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-12-17
            • 1970-01-01
            • 1970-01-01
            • 2012-02-06
            • 1970-01-01
            • 1970-01-01
            • 2018-02-13
            相关资源
            最近更新 更多