Scala的队列与并行集合
在 Scala 中,队列和并行集合是常用的数据结构和并发编程工具。
1. 队列(Queue)
- Scala 提供了可变和不可变两种队列。可变队列通过
scala.collection.mutable.Queue
类来实现,而不可变队列通过scala.collection.immutable.Queue
类来实现。 - 可变队列可以动态添加、移除和检索元素,常用的方法包括
enqueue
和dequeue
。不可变队列是持久化数据结构,每次操作都会返回一个新的队列。 - 下面是一个使用可变队列的示例:
scala
import scala.collection.mutable.Queue
val queue = Queue(1, 2, 3)
queue.enqueue(4) // 添加元素到队列末尾
val element = queue.dequeue() // 移除队列头部的元素
println(queue) // 输出 Queue(2, 3, 4)
代码示例
scala
object Test_Queue {
def main(args: Array[String]): Unit = {
// 创建一个可变队列
val queue: mutable.Queue[String] = new mutable.Queue[String]()
queue.enqueue("a", "b", "c")
println(queue)
println(queue.dequeue())
println(queue)
println(queue.dequeue())
println(queue)
queue.enqueue("d", "e")
println(queue)
println(queue.dequeue())
println(queue)
println("==========================")
// 不可变队列
val queue2: Queue[String] = Queue("a", "b", "c")
val queue3 = queue2.enqueue("d")
println(queue2)
println(queue3)
}
}
2. 并行集合(Parallel Collections)
基本介绍
-
Scala 为了充分使用多核 CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
-
主要用到的算法有:
Divide and conquer : 分治算法,Scala 通过 splitters(分解器),combiners(组合器)等抽象层来实现, 主要原理是将计算工作分解很多任务,分发给一些处理器去完成,并将它们处理结果合并返回
Work stealin 算法,主要用于任务调度负载均衡(load-balancing),通俗点完成自己的所有任务之后,发现其他人还有活没干完,主动(或被安排)帮他人一起干,这样达到尽早干完的目的。
应用案例
parallel(pærəlel 并行) 打印 1~5
scala
1 to 5).foreach(println(_)) println()
(1 to 5).par.foreach(println(_))
查看并行集合中元素访问的线程
scala
object ParDemo02 {
def main(args: Array[String]): Unit = {
val result1 = (0 to 100).map{case _ => Thread.currentThread.getName}.distinct
val result2 = (0 to 100).par.map{case _ => Thread.currentThread.getName}.distinct println(result1) //非并行
println(" ")
println(result2) //并行
}
}
-
并行集合是一种支持并发操作的集合类型,能够提高在多核处理器上的性能。Scala 提供了一系列的并行集合,如
ParArray
、ParVector
、ParRange
等。- 并行集合可以通过调用
.par
方法将普通集合转换为并行集合,然后使用.seq
方法将其恢复为普通集合。 - 并行集合支持类似于普通集合的操作和转换,但会自动并发执行以提高效率。
- 下面是一个使用并行集合的示例:
scalaval list = (1 to 10).toList val parallelList = list.par // 将列表转换为并行集合 val result = parallelList.map(_ * 2) // 并行地对每个元素进行乘以2的操作 val sequentialResult = result.seq // 将结果转换回普通列表 println(sequentialResult) // 输出 List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
- 并行集合可以通过调用
需要注意的是,并行集合的使用需要合理评估数据规模和操作的并行性,以避免不必要的开销和资源竞争。
代码示例
scala
object Test_Parallel {
def main(args: Array[String]): Unit = {
val result: immutable.IndexedSeq[Long] = (1 to 100).map(
x => Thread.currentThread.getId
)
println(result)
val result2: ParSeq[Long] = (1 to 100).par.map(
x => Thread.currentThread.getId
)
println(result2)
}
}