scala剖析PriorityQueue,权值的使用

基于堆实现的优先级队列:PriorityQueue

创建:

new PriorityQueue()(implicit ord:Ordering[A])

这里涉及到Ordering特质,看一个demo

import scala.util.Sorting
val pairs = Array(("a",5,2),("c",3,1),("b",1,3),("a",6,2))

Sorting.quickSort(pairs)(Ordering.by[(String,Int,Int),Int](_._3).reverse)
pairs.foreach(println)

Sorting.quickSort(pairs)(Ordering[(Int,String)].on(x => (x._3,x._1)))
pairs.foreach(println)

先定义一个数组,数组里面是tuple,类型为(String,Int,Int)
Sorting.quickSort其实有一些方法是包装的java中的java.util.Arrays.sort


def quickSort(a:Array[Double]):Uint = java.util.Arrays.sort(a)

其余还有Int和Float类型
而对其他自定义类型的Sort是基于Ordering特质实现的

    def quickSort[K:Ordering](a:Array[K]):Unit = ???

所以这里在第一个我们by方法实质上是

    def by[T,S](f:T => S)(implicit ord:Ordering[S]):Ordering[T] = fromLessThan((x,y) =>ord.lt(f(x),f(y)))

类似于

    def compose(x:T,y:T) = Ordering[S].compose(f(x),f(y))

也就是说这里对tuple的第三个变量进行排序,而reverse则进行逆序。

下面回归正题

PriorityQueue其实最好用的地方就是会根据进入队列元素的权进行数据的读取
这个类的使用需要隐式导入一个Ordering[A],而且按照优先级读取的方法只有dequeue和dequeueAll两个方法,drop和iterator则会移除队列中的元素。

scala剖析PriorityQueue,权值的使用_第1张图片

implicit  val ord:Ordering[(Int,String)] = Ordering.by(_._1)
val priorityDemo = collection.mutable.PriorityQueue[(Int,String)]()
priorityDemo.enqueue((2,"hello"))
priorityDemo.enqueue((5,"ct"))
priorityDemo.enqueue((1,"work"))
priorityDemo.enqueue((3,"word"))
(1 to priorityDemo.size).foreach(x =>println(priorityDemo.dequeue()))

scala剖析PriorityQueue,权值的使用_第2张图片

下面是关于一个重构技巧的:

List(1, 2, 3).foldLeft(1){(x,y) => x * y} 
List(1, 2, 3).fold(0)(_ + _) 
List(1, 2, 3).reduce(_ + _) 
List(1, 2, 3).reduceLeft(_ min _) //List(1,2,3).reduceLeft{(x,y) =>if(x<y) x else y}
List(1, 2, 3).reduce((x, y) => math.max(x, y))
After:
List(1, 2, 3).product 
List(1, 2, 3).sum 
List(1, 2, 3).sum 
List(1, 2, 3).min 
List(1, 2, 3).max

言归正传

我们本次的需求是实现一个PriorityTaskPool的类支持任意数量的处理线程,由构造参数传入,该类还应该具有一个名为asynchronous方法,其签名为

def asynchronous(priority:Int)(task: =>Int):Unit
    package com.linewell.chapter1

/** * Created by ctao on 2015/11/30. */


import scala.collection.mutable
import scala.util.Random

object AsynchronousTest extends App {

  class PriorityTaskPool(val p:Int) {

    implicit val ord: Ordering[(Int,() => Unit)] = Ordering.by(_._1)

    private val tasks = mutable.PriorityQueue[(Int,() => Unit)]()

    /** * 入队列 * @param priority 权值 * @param task 任务 */
    def asynchronous(priority: Int)(task: => Unit):Unit = tasks synchronized {
      tasks.enqueue((priority,() => task))
      tasks.notify()
    }

    class Worker extends Thread {

      setDaemon(true)

      def poll() = tasks.synchronized {
        while (tasks.isEmpty) {
          tasks.wait()
        }

        /** * 打印出task的权值 */
        println("queue: " + tasks.foldLeft("")((s,t)=>s"$s ${t._1}"))
        println(s"tasks size: ${tasks.size} ${System.currentTimeMillis()}")

        /** * 出队列 */
        tasks.dequeue()
      }

      override def run() = {
        while (true) {
          poll() match {
            case (_, task) =>

              /** * 查看当前线程 */
              print(Thread.currentThread().getName)
              task()
          }
        }
      }
    }
    //开启对应线程数量
    (1 to p).map((i) => new Worker()).foreach(_.start)

  }

  val tasks = new PriorityTaskPool(10)

  (1 to 100).foreach(i => {
    val a = Random.nextInt(10)
    tasks.asynchronous(a)({println(s"My Weight is $a ${System.currentTimeMillis()}")})
  })

  Thread.sleep(10000)
}

你可能感兴趣的:(scala)