{java.nio.file.Files.createFile`是阻塞调用吗?

时间:2019-04-27 15:50:37

标签: java scala asynchronous file-io io

java.nio.file.Files.createFile是否阻塞了调用线程?如是, 什么是创建文件/目录的非阻塞异步替代方法?

我正在寻找一种可以在java或scala中工作的简单解决方案。

1 个答案:

答案 0 :(得分:2)

文件API 中的所有操作均被阻止。执行createFile非阻塞方式的唯一方法是使用某种并发包装器,该包装器将在其他线程上执行该操作。

例如,您可以使用scala标准库中的Future

import scala.concurrent.Future
import scala.concurrent.blocking
import scala.util.{Failure, Success}

object BlockingIOExecutionContext {
   implicit val ec: ExecutionContextExecutor = ExecutionContext.fromExecutor(
      Executors.newCachedThreadPool()
   ) // create seperate thread pool for our blocking operations
}

import BlockingIOExecutionContext._ //importing our execution context for blocking operations
// alternatively if you're doing only very few IO calls just use default ExecutionContext
// import scala.concurrent.ExecutionContext.Implicits.global

val createFileFuture: Future[Path]  = Future {
  blocking { //mark this operation as blocking
    Files.createFile(Paths.get("hello"))
  }
}

createFileFuture
  .map(_.getParent) // Future is monad, so you can use map/flatMap
  .onComplete{
     case Success(parentsPath) => /* do something when file is created */
     case Failure(exception) =>  /* do something when creation fails */
  }

当您执行大量阻塞IO操作时,最好使用单独的线程池。 使用内部blocking块也是一种好习惯,因为它使ExecutionContext知道您正在执行阻塞操作。万一您一次要执行更多阻塞调用,ExecutionContext可以决定向线程池添加更多线程。

请检查此article,以获取有关使用Scala期货的更多提示。

还有其他替代方法,例如 cats-io scalaz zio monix任务,但是如果您不使用其中任何一种库,我只会呆在未来上。