Java等待线程问题

Java等待线程问题,java,multithreading,Java,Multithreading,我有一个线程,我需要等待它的结果,如下所示: t1.start(); while (variableModifiedByMyThread == null) { /* do nothing */ } // "t1" set the value of "variableModifiedByMyThread" 上面的代码正在运行,但不是一个很好的解决方案 这段代码是否也在做同样的事情(它是否在等待“t1”线程) 您的第二个代码所做的是监视t1,并等待它消失。一旦t1死亡,它将再次启动。有关该

我有一个线程,我需要等待它的结果,如下所示:

t1.start();
while (variableModifiedByMyThread == null) {
    /* do nothing */
}
// "t1" set the value of "variableModifiedByMyThread"
上面的代码正在运行,但不是一个很好的解决方案

这段代码是否也在做同样的事情(它是否在等待“t1”线程)


您的第二个代码所做的是监视t1,并等待它消失。一旦t1死亡,它将再次启动。有关该方法,请参阅。第二个代码所做的是监视t1,并等待它消失。一旦t1死亡,它将再次启动。请参阅以了解该方法。

是的,但每次检查变量都不会浪费CPU周期。这是一个更好的方法

这是假设变量仅在
t1
完成时修改。如果
t1
应该修改变量并保持活动状态,则这将不起作用

顺便说一句,你永远不应该只是像那样在一个循环中旋转等待。您至少应该在循环内部调用;否则,在允许任何其他线程运行之前,可能会进行多次循环


编辑:事实上,想想看,一个元素可能就是你真正想要的。这听起来像是生产者-消费者问题(特别是如果你不止一次这样做的话),
BlockingQueue
就是为这类事情而构建的。

是的,除非你没有浪费CPU周期,每次机会都检查变量。这是一个更好的方法

这是假设变量仅在
t1
完成时修改。如果
t1
应该修改变量并保持活动状态,则这将不起作用

顺便说一句,你永远不应该只是像那样在一个循环中旋转等待。您至少应该在循环内部调用;否则,在允许任何其他线程运行之前,可能会进行多次循环


编辑:事实上,想想看,一个元素可能就是你真正想要的。这听起来像是生产者-消费者的问题(特别是如果你不止一次这样做的话),
阻塞队列
就是为这类事情而构建的。

前者等待变量设置,后者等待线程死亡。如果变量是在螺纹刚死之前设置的,则差异不大,除了:

  • 以前的“旋转”——等待的线程一直在做一些事情(检查变量)——非常浪费
  • 后者可以被另一个线程中断

    • 前者等待变量设置,后者等待线程消亡。如果变量是在螺纹刚死之前设置的,则差异不大,除了:

      • 以前的“旋转”——等待的线程一直在做一些事情(检查变量)——非常浪费
      • 后者可以被另一个线程中断
      考虑s。这个想法是,你有一些计算将在“将来某个时候”完成,然后你可以检查它是否已经完成,或者等待它

      从javadoc:

       FutureTask<String> future =
         new FutureTask<String>(new Callable<String>() {
           public String call() {
             return searcher.search(target);
         }});
       executor.execute(future);
      
      未来任务未来=
      新建FutureTask(新的可调用(){
      公共字符串调用(){
      返回搜索者。搜索(目标);
      }});
      执行人。执行(未来);
      
      考虑s。这个想法是,你有一些计算将在“将来某个时候”完成,然后你可以检查它是否已经完成,或者等待它

      从javadoc:

       FutureTask<String> future =
         new FutureTask<String>(new Callable<String>() {
           public String call() {
             return searcher.search(target);
         }});
       executor.execute(future);
      
      未来任务未来=
      新建FutureTask(新的可调用(){
      公共字符串调用(){
      返回搜索者。搜索(目标);
      }});
      执行人。执行(未来);
      
      只要条件为真,就可以使用t1.yield()暂停线程。

      只要条件为真,就可以使用t1.yield()暂停线程。

      Upvote,但需要注意的是,您甚至不必在未来任务中包装它。。只需将其提交给ExecutorServiceUpvote,但还要注意,您甚至不必将其包装在未来任务中。。只需将其提交给ExecutorService,此处的第一个代码示例不是线程安全的。无法保证主线程在没有锁定/同步的情况下会看到对变量“variableModifiedByMyThread”所做的更改。你的主线程可能会永远旋转。你的第一个代码示例不是线程安全的。无法保证主线程在没有锁定/同步的情况下会看到对变量“variableModifiedByMyThread”所做的更改。你的主线可能会永远旋转。这是不对的,你应该防止虚假的唤醒。(请参阅java.lang.Object.wait javadoc以了解有关此操作的信息)。结果应该是:synchronized(lock){while(var==null){lock.wait();}}}这不太正确,您应该防止虚假唤醒。(请参阅java.lang.Object.wait javadoc以了解有关此操作的信息)。结果应该是:synchronized(lock){while(var==null){lock.wait();}
       FutureTask<String> future =
         new FutureTask<String>(new Callable<String>() {
           public String call() {
             return searcher.search(target);
         }});
       executor.execute(future);