This commit is contained in:
parent
d450f2096e
commit
48849063a4
@ -1,12 +1,14 @@
|
|||||||
package drills.drill03.exercise1
|
package drills.drill03.exercise1
|
||||||
|
|
||||||
|
import kotlinx.coroutines.cancelAndJoin
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import util.active.toActive
|
import util.active.toActive
|
||||||
import kotlin.time.ExperimentalTime
|
import kotlin.time.ExperimentalTime
|
||||||
import kotlin.time.measureTime
|
import kotlin.time.measureTime
|
||||||
|
|
||||||
@ExperimentalTime
|
@ExperimentalTime
|
||||||
fun main() {
|
fun main() = runBlocking {
|
||||||
val math = MathImpl().toActive(Math::class.java)
|
val (math, job) = MathImpl().toActive(Math::class.java)
|
||||||
|
|
||||||
val elapsed = measureTime {
|
val elapsed = measureTime {
|
||||||
for (i in 0 until 1000)
|
for (i in 0 until 1000)
|
||||||
@ -14,4 +16,6 @@ fun main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println("Elapsed time: $elapsed")
|
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
|
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.InvocationHandler
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.lang.reflect.Proxy
|
import java.lang.reflect.Proxy
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class ActiveObjectHandler(private val target: Any) : InvocationHandler {
|
class ActiveObjectHandler(private val target: Any) : InvocationHandler {
|
||||||
private val queue = LinkedBlockingQueue<Call>()
|
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 {
|
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
|
||||||
if (method != null && args != null)
|
if (method != null && args != null)
|
||||||
queue.add(Call(method, args))
|
queue.add(Call(method, args))
|
||||||
@ -22,6 +20,15 @@ class ActiveObjectHandler(private val target: Any) : InvocationHandler {
|
|||||||
return Unit
|
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>) {
|
data class Call(val method: Method, val args: Array<out Any>) {
|
||||||
fun executeOn(target: Any) {
|
fun executeOn(target: Any) {
|
||||||
method.invoke(target, *args)
|
method.invoke(target, *args)
|
||||||
@ -29,10 +36,16 @@ class ActiveObjectHandler(private val target: Any) : InvocationHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Any.toActive(inter: Class<T>): T {
|
fun <T> Any.toActive(inter: Class<T>): Pair<T, Job> {
|
||||||
return Proxy.newProxyInstance(
|
val active = ActiveObjectHandler(this)
|
||||||
this::class.java.classLoader,
|
|
||||||
arrayOf(inter),
|
val job = active.start()
|
||||||
ActiveObjectHandler(this)
|
|
||||||
) as T
|
return Pair(
|
||||||
|
Proxy.newProxyInstance(
|
||||||
|
this::class.java.classLoader,
|
||||||
|
arrayOf(inter),
|
||||||
|
active
|
||||||
|
) as T, job
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user