admin 管理员组

文章数量: 1087649

Kotlin入门之异步和并发

多线程的设计,在遇到需要多个执行IO操作的时候,多个线程的阻塞,造成了效率的下降,这个时候异步就是不错的选择了。

注意:下面许多操作都是新的库,比旧的版本可能没有。

  1. 异步
  • 协程
    示例:
fun main(args:Array<String>) {
//创建异步操作val job = launch(search())println("Hello, ")//等待job执行结束,程序结束job.join()}
suspend fun search(){
//delay只能在协程内部或者suspend函数中执行delay(1000L)println("World!")
}
  • 同步方式写异步代码
    实例:
fun main(args:Array<String>)= runBlocking<Unit>{val one = async{ searchItemOne() }val two = async{ searchItemTwo() }println("The item is ${one.await()} and ${two.await()}")
}
  1. 并发
    使用@Synchronized保证整个函数或者synchronized()保证一部分代码块。
class Shop{val goods = hashMapOf<Long, Int>()init {goods.put(1, 10)goods.put(2, 15)}@Synchronized fun buyGoods(id: Long){val stock = goods.getValue(id)goods.put(id, stock - 1)}fun buyGoods2(id: Long){synchronized(this){val stock  = goods.getValue(id)goods.put(id, stock - 1)}}
}

另外,Kotlin中的Akka也是基于Actor的不错的选择。

  • Akka
    Akka共享内存的设计理念和传统不同,Actor模型提倡的是:通过通信来实现共享内存,而不是共享内存来实现通信。
    原则:
  1. 消息的发送必须先于消息的接收。
  2. 同一个Actor对一条消息的处理先于对于下一条消息的处理。
    示例:
import akka.actor.ActorRef
import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.UntypedAbstractActor
import akka.pattern.Patterns
import akka.util.Timeout
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import java.util.*
class ShopActor(val stocks:HashMap<Long, Int>):UntypedAbstractActor(){var orderNumber = 1Loverride fun onReceive(message: Any?){when(message){is Action.Buy -> {val stock  = stock.getValue(message.id)if(stock > message.amount){stocks.plus(Pair(message.id, stock - message.amount))sender.tell(orderNumber, self)orderNumber++} else {sender.tell("low stock", self)}}is Action.GetStock -> {sender.tell(stocks.get(message.id), self)}}}
}
sealed class Action{data class BuyOrInit(...):Action()//参数省略data class Buy(val id:Long, val userId:Long, val amount:Long):Action()data class GetStock(val id:Long):Action()data class GetStockOrInit(....)
}
class ManageActor: UntypedAbstractActor(){override fun onReceive(message: Any?){when(message){is Action.BuyOrInit -> getOrInit(message.shopName, message.stocks).forward(Action.Buy(message.id, message.userId, message.amount), context)is Action.GetStockOrInit -> getOrInit(message.shopName,message.stocks).forward(Action.GetStock(message.id), context)}}fun getOrInit(shopName:String, stocks:Map<Long, Int>:ActorRef{return context.findChild("shop-actor-${shopName}").orElseGet{context.actorOf(Props.create(ShopActor::class.java, stocks), "shop-actor-${shopName}")}}
}
fun main(args:Array<String>){val stocksA = hashMapOf(Pair(1L, 10), Pair(2L, 5), Pair(3L, 20))val stockB =  hashMapOf(Pair(1L, 15), Pair(2L, 8), Pair(3L, 30))val actorSystem = ActorSystem.apply("shop-system")val manageActor = actorSystem.actorOf(Props.create(ManageActor::class.java),"manage-actor")val timeout = Timeout(Duration.create(3, "second")val resA = Patterns.ask(manageActor, Action.GetStockOrInit(1L, "A", stocksA), timeout)val stock = Await.result(resA, timeout.duration())println("the stock is ${stock}")val resB = Patterns.ask(manageActor, Action.BuyOrInit(2L, 1L, 1, "b", stocksB), timeout)val orderNumber = Await.result(resB, timeout.duration())println("the orderNumber is ${orderNumber}")
}

本文标签: Kotlin入门之异步和并发