2

以下のコードでは、まず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
}
4

0 に答える 0