2

在下面的代码中,首先我们可以通过调用create方法来创建东西,而销毁它可以调用destroy方法,每个方法首先改变对象的状态,然后异步等待操作时间到。假设创建时间为 10 秒,销毁时间为 5 秒。当我调用destroy方法时,它将destroying布尔值更改为true,然后等待创建持续时间的另一个线程将中断该waitUntil方法中的循环。但它不能正常工作。当我调用 create 方法时,它会更改状态,然后创建一个线程以等待创建持续时间的时间增加。调用create方法后,我调用destroy方法如下:

    map(0, 0).create(....)
    map(0, 0).destroy(....)

但是在destroy方法中更改destroying变量并没有使创建块中的另一个线程中断,它会一直持续到持续时间结束。

@volatile
protected var status: UnitStatus = UnitStatus.NEED_TO_CREATE

@volatile
protected var destroying = false

def destroy(f: Int => Unit): Unit = status match {
    case UnitStatus.DESTROYED => {
        throw new UnitAlreadyDestroyedException
    }
    case UnitStatus.DESTROYING =>
    case UnitStatus.PREPARED_TO_DESTROY => {
        destroying = true
        status = UnitStatus.DESTROYING
        async {
            waitUntil(destroyDuration, UnitStatus.DESTROYED) {
                f
            }
        }

    }
}

def create(f: Int => Unit): Unit = status match {
    case UnitStatus.DESTROYED => throw new UnitAlreadyDestroyedException
    case UnitStatus.NEED_TO_CREATE => {
        ResourcesContainer -= creationCost
        status = UnitStatus.CONSTRUCTION
        async {
            waitUntil(creationDuration, UnitStatus.READY) {
                f
            }
        }
    }
    case _ => throw new UnitAlreadyCreatedException
}

def waitUntil(seconds: Int, finalState: UnitStatus)(f: Int => Unit): Unit = {
    var timeElapse = 0
    var percent: Int = 0

    breakable {
        while (timeElapse < seconds) {
            val destroyState = isInDestroyState
            if (destroying && !destroyState) {
                break() // **program does not enter to this part of code**
            }
            timeElapse += 1
            percent = ((timeElapse.asInstanceOf[Float] / seconds) * 100).toInt
            f(percent)
            Thread.sleep(1000)
        }
        if (status != null) {
            status = finalState
        }
    }

}

def async[T](fn: => Unit): Unit = scala.actors.Actor.actor {
    fn
}

def isInDestroyState: Boolean = {
    status == UnitStatus.DESTROYED ||
        status == UnitStatus.DESTROYING ||
        status == UnitStatus.PREPARED_TO_DESTROY
}
4

0 回答 0