Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

concurrent Future failed when function called #12278

Closed
conderls opened this issue Dec 9, 2020 · 3 comments
Closed

concurrent Future failed when function called #12278

conderls opened this issue Dec 9, 2020 · 3 comments

Comments

@conderls
Copy link

conderls commented Dec 9, 2020

reproduction steps

using Scala (2.11.12, 2.12),

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._

object FutureTest {
  def printIdInfo(id: Long): String = {
    if (id % 2 == 0) {
      "even:%s".format(id)
    } else {
      "odd:%s".format(id)
    }
  }

  println(s"Current thread: ${printIdInfo(Thread.currentThread().getId)}")
  val future: Future[Unit] = Future(println {
    s"Thread id in future: ${printIdInfo(Thread.currentThread().getId)}."
  })

  Await.result(future, 2.seconds)
  println("Future has been executed")
}

FutureTest

problem

(explain how the above behavior isn't what you expected)

Current thread: odd:1
java.lang.NoClassDefFoundError: Could not initialize class $line6.$read$$iw$$iw$$iw$$iw$FutureTest$
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
        at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:659)
        at scala.util.Success.$anonfun$map$1(Try.scala:255)
        at scala.util.Success.map(Try.scala:213)
        at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
        at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
        at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
java.util.concurrent.TimeoutException: Futures timed out after [2 seconds]
  at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:259)
  at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:263)
  at scala.concurrent.Await$.$anonfun$result$1(package.scala:223)
  at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:57)
  at scala.concurrent.Await$.result(package.scala:146)
  ... 30 elided
@SethTisue
Copy link
Member

is the problem reproducible in Scala 2.13.4?

@som-snytt
Copy link

This is "don't kick off threads from object initializer because it can lead to deadlock," which is attested by many tickets.

Here, the deadlock is explicit: the future is blocked on object initialization, which can't complete because of Await.

import concurrent.{Await => `Oh, wait!`}

@som-snytt
Copy link

som-snytt commented Dec 9, 2020

As a refresher, "fixed in dotty" because bootstrap methods are non-static so the future lambda does not block for static init of module. However, fields are static, so any data references will deadlock again.

The more exact duplicate is #10782

#9076

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants