0
從«學習Scala的併發編程»一個例子:爲什麼此代碼無法刪除文件?
package org.learningconcurrency
import java.io.File
import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.{ConcurrentHashMap, ForkJoinPool, LinkedBlockingQueue}
import org.apache.commons.io.FileUtils
import scala.annotation.tailrec
/**
* Created by kaiyin on 1/19/16.
*/
import org.learningconcurrency.ch3.Ch3.execute
import scala.collection.convert.decorateAsScala._
object Issue {
sealed trait State
class Idle extends State
class Creating extends State
class Copying(val n: Int) extends State
class Deleting extends State
class Entry(val isDir: Boolean) {
val state = new AtomicReference[State](new Idle)
}
class FileSystem(val root: String) {
val rootDir = new File(root)
val files: collection.concurrent.Map[String, Entry] = new ConcurrentHashMap[String, Entry]().asScala
for (f <- FileUtils.iterateFiles(rootDir, null, false).asScala)
files.put(f.getName, new Entry(false))
def deleteFile(filename: String): Unit = {
files.get(filename) match {
case None =>
log(s"Path '$filename' does not exist!")
case Some(entry) if entry.isDir =>
log(s"Path '$filename' is a directory!")
case Some(entry) => execute {
if (prepareForDelete(entry))
if (FileUtils.deleteQuietly(new File(filename)))
files.remove(filename)
}
}
}
}
@tailrec private def prepareForDelete(entry: Entry): Boolean = {
val s0 = entry.state.get
s0 match {
case i: Idle =>
if (entry.state.compareAndSet(s0, new Deleting)) true
else prepareForDelete(entry)
case c: Creating =>
log("File is being created, cannot delete")
false
case c: Copying =>
log("File is being created, cannot delete")
false
case d: Deleting =>
false
}
}
def main(args: Array[String]) {
val fs = new FileSystem("/tmp")
fs.files.foreach(println _)
// Thread.sleep(500)
fs.deleteFile("test")
}
}
它只是檢查一個文件的狀態,然後將其刪除,並且代碼看起來像它應該工作,但它運行後,這個文件我已創建touch /tmp/test
仍在那裏。