This commit is contained in:
parent
d450f2096e
commit
48849063a4
@ -1,12 +1,14 @@
|
||||
package drills.drill03.exercise1
|
||||
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import util.active.toActive
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlin.time.measureTime
|
||||
|
||||
@ExperimentalTime
|
||||
fun main() {
|
||||
val math = MathImpl().toActive(Math::class.java)
|
||||
fun main() = runBlocking {
|
||||
val (math, job) = MathImpl().toActive(Math::class.java)
|
||||
|
||||
val elapsed = measureTime {
|
||||
for (i in 0 until 1000)
|
||||
@ -14,4 +16,6 @@ fun main() {
|
||||
}
|
||||
|
||||
println("Elapsed time: $elapsed")
|
||||
|
||||
job.cancelAndJoin()
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
package drills.drill03.exercise3
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class AddTask(private val a: Int, private val b: Int) : Task {
|
||||
override fun execute(): Serializable = a + b
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package drills.drill03.exercise3
|
||||
|
||||
import util.rmi.Client
|
||||
|
||||
fun main() {
|
||||
Client(clientHandler).start()
|
||||
}
|
||||
|
||||
val clientHandler = {
|
||||
val rev = Client.lookup("rev") as Rev
|
||||
|
||||
println("Enter two numbers:")
|
||||
val a = readLine()?.toInt() ?: 0
|
||||
val b = readLine()?.toInt() ?: 0
|
||||
|
||||
val sum = rev.executeTask(AddTask(a, b))
|
||||
println("The sum of $a and $b is $sum")
|
||||
|
||||
println("Enter the number of which you want to calculate the factorial:")
|
||||
val n = readLine()?.toInt() ?: 0
|
||||
|
||||
val fact = rev.executeTask(FactTask(n))
|
||||
println("The factorial of $n is $fact")
|
||||
}
|
||||
|
||||
fun fact(n: Int): Long = if (n <= 1) 1 else n * fact(n - 1)
|
@ -1,9 +0,0 @@
|
||||
package drills.drill03.exercise3
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class FactTask(private val n: Int) : Task {
|
||||
override fun execute(): Serializable = fact(n)
|
||||
|
||||
private fun fact(n: Int): Long = if (n <= 1) 1 else n * fact(n - 1)
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package drills.drill03.exercise3
|
||||
|
||||
import java.io.Serializable
|
||||
import java.rmi.Remote
|
||||
import java.rmi.RemoteException
|
||||
import java.rmi.server.UnicastRemoteObject
|
||||
|
||||
interface Rev : Remote {
|
||||
@Throws(RemoteException::class)
|
||||
fun executeTask(task: Task): Serializable
|
||||
}
|
||||
|
||||
class RevImpl : Rev, UnicastRemoteObject() {
|
||||
override fun executeTask(task: Task): Serializable = task.execute()
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package drills.drill03.exercise3
|
||||
|
||||
import util.rmi.Server
|
||||
|
||||
fun main() {
|
||||
Server {
|
||||
System.setSecurityManager(SecurityManager())
|
||||
val rev: Rev = RevImpl()
|
||||
Server.bind(rev, "rev")
|
||||
}.start()
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package drills.drill03.exercise3
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
interface Task : Serializable {
|
||||
fun execute(): Serializable
|
||||
}
|
@ -1,20 +1,18 @@
|
||||
package util.active
|
||||
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.reflect.InvocationHandler
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Proxy
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ActiveObjectHandler(private val target: Any) : InvocationHandler {
|
||||
private val queue = LinkedBlockingQueue<Call>()
|
||||
|
||||
init {
|
||||
Thread {
|
||||
while (true)
|
||||
queue.take().executeOn(target)
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
|
||||
if (method != null && args != null)
|
||||
queue.add(Call(method, args))
|
||||
@ -22,6 +20,15 @@ class ActiveObjectHandler(private val target: Any) : InvocationHandler {
|
||||
return Unit
|
||||
}
|
||||
|
||||
fun start(): Job {
|
||||
return GlobalScope.launch {
|
||||
while (isActive || queue.isNotEmpty()) {
|
||||
queue.poll(100, TimeUnit.MILLISECONDS)
|
||||
?.executeOn(target) ?: continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Call(val method: Method, val args: Array<out Any>) {
|
||||
fun executeOn(target: Any) {
|
||||
method.invoke(target, *args)
|
||||
@ -29,10 +36,16 @@ class ActiveObjectHandler(private val target: Any) : InvocationHandler {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Any.toActive(inter: Class<T>): T {
|
||||
return Proxy.newProxyInstance(
|
||||
this::class.java.classLoader,
|
||||
arrayOf(inter),
|
||||
ActiveObjectHandler(this)
|
||||
) as T
|
||||
fun <T> Any.toActive(inter: Class<T>): Pair<T, Job> {
|
||||
val active = ActiveObjectHandler(this)
|
||||
|
||||
val job = active.start()
|
||||
|
||||
return Pair(
|
||||
Proxy.newProxyInstance(
|
||||
this::class.java.classLoader,
|
||||
arrayOf(inter),
|
||||
active
|
||||
) as T, job
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user