以下のコードでは、まずcreate
メソッドを呼び出して何かを作成し、それを破棄するためにメソッドを呼び出すことができますdestroy
。各メソッドは最初にオブジェクトのステータスを変更し、操作の時間が経過するまで非同期に待機します。作成時間を 10 秒、破棄時間を 5 秒とします。destroy メソッドを呼び出すと、destroying
ブール値が true に変更され、作成期間を待機している別のスレッドがwaitUntil
メソッド内のループを中断します。しかし、それは正しく動作しません。createメソッドを呼び出すと、ステータスが変更され、スレッドが作成され、作成期間の時間が経過するまで待機します。create メソッドを呼び出した後、以下のように destroy メソッドを呼び出します。
map(0, 0).create(....)
map(0, 0).destroy(....)
ただしdestroying
、destroy メソッドで変数を変更しても、作成中のブロックにある別のスレッドが中断することはなく、期間が終了するまで継続します。
@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
}