使用Scala实现一个并发库(NonBlocking版本)

M24C04-R EEPROM与R7FA4M3AF3CFB144 MCU的嵌入式存储方案 在嵌入式系统开发中,非易失性存储技术是确保数据持久化的关键。EEPROM作为一种经典的存储介质,以其百万次擦写周期和长达40年的数据保持能力,成为工业级应用的理想选择。通过I2C总线协议,EEPROM可以与微控制器高效通信,实现数据的可靠存储与读取。本文以M24C04-R EEPROM与瑞萨R7FA4M3AF3CFB144 MCU的组合为例,详细解析了硬件连接、软件驱动及高级应用技巧。特别是在工业环境中,通过CRC8校验和磨损均衡策略,显著提升了数据可靠性和存储寿命。这些实践不仅适用于温控器、智能电表等场景 阅读详情

这个例子来源于scala圣经级教程《Functional Programming in Scala》,由于本人跟着书中的代码敲了一遍,然后写了点测试代码验证了一下正确性,所以就放在这做个备忘吧。贴出来只是为了方便自己,如果看不懂,但是又感兴趣的就去看原书吧……

> 注:本文是上一篇文章《使用Scala实现一个并发库(阻塞版本, 下一篇文章提供NonBlocking版本)》的延续

package parallelism

import java.util.concurrent._
import java.util.concurrent.atomic.AtomicReference

import parallelism.Nonblocking.Future

import language.implicitConversions

object Nonblocking {

  trait Future[+A] {
    private[parallelism] def apply(k: A => Unit): Unit
  }

  type Par[+A] = ExecutorService => Future[A]

  object Par {

    def run[A](es: ExecutorService)(p: Par[A]): A = {
      // A mutable, threadsafe reference, to use for storing the result
      val ref = new java.util.concurrent.atomic.AtomicReference[A]
      // A latch which, when decremented, implies that `ref` has the result
      val latch = new CountDownLatch(1)
      // Asynchronously set the result, and decrement the latch
      p(es) { a => ref.set(a); latch.countDown }
      // Block until the `latch.countDown` is invoked asynchronously
      latch.await
      // Once we've passed the latch, we know `ref` has been set, and return its value
      ref.get
    }

    def unit[A](a: A): Par[A] =
      es => new Future[A] {
        def apply(cb: A => Unit): Unit =
          cb(a)
      }

    /** A non-strict version of `unit` */
    def delay[A](a: => A): Par[A] =
      es => new Future[A] {
        def apply(cb: A => Unit): Unit =
          cb(a)
      }

    def fork[A](a: => Par[A]): Par[A] =
      es => new Future[A] {
        def apply(cb: A => Unit): Unit =
          eval(es)(a(es)(cb))
      }

    /**
      * Helper function for constructing `Par` values out of calls to non-blocking continuation-passing-style APIs.
      * This will come in handy in Chapter 13.
      */
    def async[A](f: (A => Unit) => Unit): Par[A] = es => new Future[A] {
      def apply(k: A => Unit) = f(k)
    }

    /**
      * Helper function, for evaluating an action
      * asynchronously, using the given `ExecutorService`.
      */
    def eval(es: ExecutorService)(r: => Unit): Unit =
      es.submit(new Callable[Unit] {
        def call = r
      })

    def map2[A, B, C](p: Par[A], p2: Par[B])(f: (A, B) => C): Par[C] =
      es => new Future[C] {
        def apply(cb: C => Unit): Unit = {
          var ar: Option[A] = None
          var br: Option[B] = None
          // this implementation is a little too liberal in forking of threads -
          // it forks a new logical thread for the actor and for stack-safety,
          // forks evaluation of the callback `cb`
          val combiner = Actor[Either[A, B]](es) {
            case Left(a) =>
              if (br.isDefined) eval(es)(cb(f(a, br.get)))
              else ar = Some(a)
            case Right(b) =>
              if (ar.isDefined) eval(es)(cb(f(ar.get, b)))
              else br = Some(b)
          }
          p(es)(a => combiner ! Left(a))
          p2(es)(b => combiner ! Right(b))
        }
      }

    // specialized version of `map`
    def map[A, B](p: Par[A])(f: A => B): Par[B] =
      es => new Future[B] {
        def apply(cb: B => Unit): Unit =
          p(es)(a => eval(es) {
            cb(f(a))
          })
      }

    def lazyUnit[A](a: => A): Par[A] =
      fork(unit(a))

    def asyncF[A, B](f: A => B): A => Par[B] =
      a => lazyUnit(f(a))

    def sequenceRight[A](as: List[Par[A]]): Par[List[A]] =
      as match {
        case Nil => unit(Nil)
        case h :: t => map2(h, fork(sequence(t)))(_ :: _)
      }

    def sequenceBalanced[A](as: IndexedSeq[Par[A]]): Par[IndexedSeq[A]] = fork {
      if (as.isEmpty) unit(Vector())
      else if (as.length == 1) map(as.head)(a => Vector(a))
      else {
        val (l, r) = as.splitAt(as.length / 2)
        map2(sequenceBalanced(l), sequenceBalanced(r))(_ ++ _)
      }
    }

    def sequence[A](as: List[Par[A]]): Par[List[A]] =
      map(sequenceBalanced(as.toIndexedSeq))(_.toList)

    def parMap[A, B](as: List[A])(f: A => B): Par[List[B]] =
      sequence(as.map(asyncF(f)))

    def parMap[A, B](as: IndexedSeq[A])(f: A => B): Par[IndexedSeq[B]] =
      sequenceBalanced(as.map(asyncF(f)))

    // exercise answers

    /*
     * We can implement `choice` as a new primitive.
     *
     * `p(es)(result => ...)` for some `ExecutorService`, `es`, and
     * some `Par`, `p`, is the idiom for running `p`, and registering
     * a callback to be invoked when its result is available. The
     * result will be bound to `result` in the function passed to
     * `p(es)`.
     *
     * If you find this code difficult to follow, you may want to
     * write down the type of each subexpression and follow the types
     * through the implementation. What is the type of `p(es)`? What
     * about `t(es)`? What about `t(es)(cb)`?
     */
    def choice[A](p: Par[Boolean])(t: Par[A], f: Par[A]): Par[A] =
      es => new Future[A] {
        def apply(cb: A => Unit): Unit =
          p(es) { b =>
            if (b) eval(es) {
              t(es)(cb)
            }
            else eval(es) {
              f(es)(cb)
            }
          }
      }

    /* The code here is very similar. */
    def choiceN[A](p: Par[Int])(ps: List[Par[A]]): Par[A] =
      es => new Future[A] {
        def apply(cb: A => Unit): Unit =
          p(es) { ind =>
            eval(es) {
              ps(ind)(es)(cb)
            }
          }
      }

    def choiceViaChoiceN[A](a: Par[Boolean])(ifTrue: Par[A], ifFalse: Par[A]): Par[A] =
      choiceN(map(a)(b => if (b) 0 else 1))(List(ifTrue, ifFalse))

    def choiceMap[K, V](p: Par[K])(ps: Map[K, Par[V]]): Par[V] =
      es => new Future[V] {
        def apply(cb: V => Unit): Unit =
          p(es)(k => ps(k)(es)(cb))
      }

    /* `chooser` is usually called `flatMap` or `bind`. */
    def chooser[A, B](p: Par[A])(f: A => Par[B]): Par[B] =
      flatMap(p)(f)

    def flatMap[A, B](p: Par[A])(f: A => Par[B]): Par[B] =
      es => new Future[B] {
        def apply(cb: B => Unit): Unit =
          p(es)(a => f(a)(es)(cb))
      }

    def choiceViaFlatMap[A](p: Par[Boolean])(f: Par[A], t: Par[A]): Par[A] =
      flatMap(p)(b => if (b) t else f)

    def choiceNViaFlatMap[A](p: Par[Int])(choices: List[Par[A]]): Par[A] =
      flatMap(p)(i => choices(i))

    def join[A](p: Par[Par[A]]): Par[A] =
      es => new Future[A] {
        def apply(cb: A => Unit): Unit =
          p(es)(p2 => eval(es) {
            p2(es)(cb)
          })
      }

    def joinViaFlatMap[A](a: Par[Par[A]]): Par[A] =
      flatMap(a)(x => x)

    def flatMapViaJoin[A, B](p: Par[A])(f: A => Par[B]): Par[B] =
      join(map(p)(f))

    /* Gives us infix syntax for `Par`. */
    implicit def toParOps[A](p: Par[A]): ParOps[A] = new ParOps(p)

    // infix versions of `map`, `map2` and `flatMap`
    class ParOps[A](p: Par[A]) {
      def map[B](f: A => B): Par[B] = Par.map(p)(f)

      def map2[B, C](b: Par[B])(f: (A, B) => C): Par[C] = Par.map2(p, b)(f)

      def flatMap[B](f: A => Par[B]): Par[B] = Par.flatMap(p)(f)

      def zip[B](b: Par[B]): Par[(A, B)] = p.map2(b)((_, _))
    }

  }


  def main(args: Array[String]): Unit = {

    // _print for dubug purpose
    val _print = (flag: Boolean) => if (flag) println(": " + Thread.currentThread()) else println(Thread.currentThread())

    val es = Executors.newFixedThreadPool(3)

    val intDelayPar = Par.delay[Int]({
      _print(false);
      math.pow(999, 67).toInt
    });

    intDelayPar(es).apply((a: Int) => {
      _print(true);
      println(a)
    })

    intDelayPar(es)((a: Int) => {
      _print(true);
      println(a)
    })

    Par.fork(intDelayPar)(es)((a: Int) => {
      _print(true);
      println(a)
    })


    Thread.sleep(6000L)
    println("**********************************************")

    Par.run(es)(intDelayPar)

    Thread.sleep(6000L)
    println("**********************************************")


    val _intDelayPar = Par.delay[Int]({
      val future = es.submit(new Callable[Int] {
        _print(true);
        override def call = math.pow(999, 67).toInt
      })
      val res = future.get
      println(res)
      res
    });
    Par.run(es)(_intDelayPar)

    println("-------------------------------------------")

    import scala.language.implicitConversions
    import Par.toParOps

    // 通过隐式转换将 map 方法变为中缀操作方式
    (Par.delay(1) map {(a: Int) => 111 * a})(es)(println(_))
    (Par.delay(2) map {(a: Int) => 111 * a})(es)(println(_))
    (Par.delay(3) map {(a: Int) => 111 * a})(es)(println(_))

    es.shutdown()
  }

}

上述代码的运行结果是:


Thread[main,5,main]
: Thread[main,5,main]
2147483647
Thread[main,5,main]
: Thread[main,5,main]
2147483647
Thread[pool-1-thread-1,5,main]
: Thread[pool-1-thread-1,5,main]
2147483647
**********************************************
Thread[main,5,main]
**********************************************
: Thread[main,5,main]
2147483647
-------------------------------------------
111
222
333

上述代码用到的Actor源码是:

package parallelism

import java.util.concurrent.atomic.{AtomicInteger, AtomicReference}
import java.util.concurrent.{Callable,ExecutorService}
import annotation.tailrec

/*
 * Implementation is taken from `scalaz` library, with only minor changes. See:
 *
 * https://github.com/scalaz/scalaz/blob/scalaz-seven/concurrent/src/main/scala/scalaz/concurrent/Actor.scala
 *
 * This code is copyright Andriy Plokhotnyuk, Runar Bjarnason, and other contributors,
 * and is licensed using 3-clause BSD, see LICENSE file at:
 *
 * https://github.com/scalaz/scalaz/blob/scalaz-seven/etc/LICENCE
 */

/**
 * Processes messages of type `A`, one at a time. Messages are submitted to
 * the actor with the method `!`. Processing is typically performed asynchronously,
 * this is controlled by the provided `strategy`.
 *
 * Memory consistency guarantee: when each message is processed by the `handler`, any memory that it
 * mutates is guaranteed to be visible by the `handler` when it processes the next message, even if
 * the `strategy` runs the invocations of `handler` on separate threads. This is achieved because
 * the `Actor` reads a volatile memory location before entering its event loop, and writes to the same
 * location before suspending.
 *
 * Implementation based on non-intrusive MPSC node-based queue, described by Dmitriy Vyukov:
 * [[http://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue]]
 *
 * @see scalaz.concurrent.Promise for a use case.
 *
 * @param handler  The message handler
 * @param onError  Exception handler, called if the message handler throws any `Throwable`.
 * @param strategy Execution strategy, for example, a strategy that is backed by an `ExecutorService`
 * @tparam A       The type of messages accepted by this actor.
 */
final class Actor[A](strategy: Strategy)(handler: A => Unit, onError: Throwable => Unit = throw(_)) {
  self =>

  private val tail = new AtomicReference(new Node[A]())
  private val suspended = new AtomicInteger(1)
  private val head = new AtomicReference(tail.get)

  /** Alias for `apply` */
  def !(a: A) {
    val n = new Node(a)
    head.getAndSet(n).lazySet(n)
    trySchedule()
  }

  /** Pass the message `a` to the mailbox of this actor */
  def apply(a: A) {
    this ! a
  }

  def contramap[B](f: B => A): Actor[B] =
    new Actor[B](strategy)((b: B) => (this ! f(b)), onError)

  private def trySchedule() {
    if (suspended.compareAndSet(1, 0)) schedule()
  }

  private def schedule() {
    strategy(act())
  }

  private def act() {
    val t = tail.get
    val n = batchHandle(t, 1024)
    if (n ne t) {
      n.a = null.asInstanceOf[A]
      tail.lazySet(n)
      schedule()
    } else {
      suspended.set(1)
      if (n.get ne null) trySchedule()
    }
  }

  @tailrec
  private def batchHandle(t: Node[A], i: Int): Node[A] = {
    val n = t.get
    if (n ne null) {
      try {
        handler(n.a)
      } catch {
        case ex: Throwable => onError(ex)
      }
      if (i > 0) batchHandle(n, i - 1) else n
    } else t
  }
}

private class Node[A](var a: A = null.asInstanceOf[A]) extends AtomicReference[Node[A]]

object Actor {

  /** Create an `Actor` backed by the given `ExecutorService`. */
  def apply[A](es: ExecutorService)(handler: A => Unit, onError: Throwable => Unit = throw(_)): Actor[A] =
    new Actor(Strategy.fromExecutorService(es))(handler, onError)
}

/**
 * Provides a function for evaluating expressions, possibly asynchronously.
 * The `apply` function should typically begin evaluating its argument
 * immediately. The returned thunk can be used to block until the resulting `A`
 * is available.
 */
trait Strategy {
  def apply[A](a: => A): () => A
}

object Strategy {

  /**
   * We can create a `Strategy` from any `ExecutorService`. It's a little more
   * convenient than submitting `Callable` objects directly.
   */
  def fromExecutorService(es: ExecutorService): Strategy = new Strategy {
    def apply[A](a: => A): () => A = {
      val f = es.submit { new Callable[A] { def call = a} }
      () => f.get
    }
  }

  /**
   * A `Strategy` which begins executing its argument immediately in the calling thread.
   */
  def sequential: Strategy = new Strategy {
    def apply[A](a: => A): () => A = {
      val r = a
      () => r
    }
  }
}
879675643@qq.com  lhever

.---.                                                                         
|   |   .              __.....__   .----.     .----.   __.....__              
|   | .'|          .-''         '.  \    \   /    /.-''         '.            
|   |<  |         /     .-''"'-.  `. '   '. /'   //     .-''"'-.  `. .-,.--.  
|   | | |        /     /________\   \|    |'    //     /________\   \|  .-. | 
|   | | | .'''-. |                  ||    ||    ||                  || |  | | 
|   | | |/.'''. \\    .-------------''.   `'   .'\    .-------------'| |  | | 
|   | |  /    | | \    '-.____...---. \        /  \    '-.____...---.| |  '-  
|   | | |     | |  `.             .'   \      /    `.             .' | |      
'---' | |     | |    `''-...... -'      '----'       `''-...... -'   | |      
      | '.    | '.                                                   |_|      
      '---'   '---'  
scala并发编程开发教程 Spark 的RPC是通过Akka类库实现的,Akka用Scala语言开发,基于Actor并发模型实现 立即下载

相关推荐

Utrust4701F与Utrust2700R读写器在银河麒麟系统的安装及测试步骤说明

Utrust4701F与Utrust2700R读写器支持银河麒麟系统,广泛应用会员管理、支付管理等领域。本文将重点介绍Utrust4701F与Utrust2700R读写器在银河麒麟系统的安装及测试步骤说明。以上方法适用于主流国产操作系统,如 优麒麟(UbuntuKylin)/ 中标麒麟(NeoKylin) / UOS(统信操作系统)/ 中兴新支点 / 红旗 linux(redflag linux)/ 普华 Linux(I-soft OS) / 威科乐恩 Linux(WiOS)等

华翔天诚科技 1834

scala并发_探索Scala并发

2003年,Herb Sutter在他的“免费午餐结束了”一文中揭露了业界最大的“肮脏小秘密”,清楚地表明,越来越快的处理器时代已经结束,将由一个新的并行化时代取代。单个芯片上的“核心”(虚拟CPU)。 这个消息在编程界引起了震惊,因为正确地保持线程安全的代码一直都存在,从理论上讲,即使不是在实践中,高能力的软件开发人员也对您的公司而言过于昂贵。 似乎很少有特权的人对Java的线程模型和并发A...

cusi77914的博客 758

大麦网抢票软件工具开发系列(一)

前言《大麦网》都知道吧,就是那个被网友声称“大麦网你卖啥了?”票务平台。近期有听到朋友说《大麦网》的票很难抢,基本上都是说:“哎哟喂,被挤爆啦,请稍后重试!”,也不知道《大麦网》...

架构文摘 1万+

【Scala笔记——道】给你的Future一个Promise --最浪漫的并发模型(一)

Future 曾经,她在他的臂弯中,星空下,问他:“会不会一直对我这么好”, “你会不会在五年后来娶我”… Future 和 Promise Future 代表未来。未来总会来到,但这个未来是成功或是失败我们不得而之。抽象为核心三个方法 `onComplete’, ’onSuccess’, ‘onFailure’。其中 onSuccess和 onFailure是 onComplete的简化。"...

Contributor -> Committer 1269

Uds诊断自动化(CANoe.diva应用)

(7)其他配置选择可以保持默认(一般情况下,DTC以及31服务、下载服务需要另外测试)。(1)打开CANoe.Diva软件,并新建Diva工程。(2)设置工程名和保存位置;在"Specification file"(3)测试案例打开后的界面如下,可以对要进行测试的案例进行勾选,(可查看下角的进度条)后;(3)等待DIva工程的生成;(4)接下来是修改Diva工程选项,如下图点击。,如用例间的时间间隔、复位等待时间等。,即可打开导入的测试工程。,即可生成测试用例。(1)在CANoe中。

LIUJIAAAAA的博客 3446

模糊综合评价模型

一.引子 1.数学归纳法:同高中知识 2.秃子悖论:秃子悖论 这俩个例子都是类似于“量变引起质变”的道理,而在数学中我们把这类问题的性质叫做“模糊性”,在生活中我们也经常能遇到一些模糊的概念,比如年轻、帅、很少很多… 二.概述 模糊综合评价法是一种基于模糊数学的综合评价方法。该综合评价法根据模糊数学的隶属度理论把定性评价转化为定量评价,即用模糊数学对受到多种因素制约的事物或对象做出一个总体的评价。它具有结果清晰,系统性强的特点,能较好地解决模糊的、难以量化的问题,适合各种非确定性问题的解决。——来自百度百

The__Tyche的博客 2万+

Scala Actor并发编程

Scala 并发编程介绍,Scala Actor实例及匿名Actor创建方法。最后介绍Scala Actor和case class 以及接收回传消息的方法。

残缺的孤独 4877

Qt Design Studio 入门指南:从零开始打造炫酷UI(详细+实用+轻松上手)

本文是Qt Design Studio的详细入门指南,旨在帮助UI设计新手从零开始轻松打造炫酷界面。文章系统介绍了软件的核心概念、安装步骤、主界面解析,并通过创建一个完整的登录界面实例,手把手教学如何拖拽组件、设置属性、添加交互状态与动画。同时,分享了创建自定义组件、管理资源以及提升效率的实用技巧与常见问题解决方案,让读者能够快速上手并应用于实际项目开发。

devops8pract的博客 592

Java并发包源码分析

  并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力。如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善。现代的PC都有多个CPU或一个CPU中有多个核,是否能合理运用多核的能力将成为一个大规模应用程序的关键。   Java基础部分知识总结点击Java并发基础总结。Java多线程相关类的实现都在Java的并发包concurrent,concur...

weixin_33989780的博客 398

【异常】Claude Code CLI工具 模型加载异常 /init报错排查与完整解决方案 There‘s an issue with the selected model (glm-5). It

此类跨厂商模型配置报错,核心诱因是API生态的兼容性不匹配。优先使用工具原生支持的模型体系,可快速解决90%以上的同类报错;若需跨厂商使用目标模型,需完成API端点、鉴权密钥、模型ID的全链路适配,确保全流程配置合规,即可完成异常修复。

奶爸的编程之路,也就一周冷个三天 3705

OpenHarmony WiFi子系统全解析:从架构到代码实现(大合集)

头文件路径[相对路径][相对路径][相对路径][相对路径]// 网络配置结构 (wifi_device_config.h)// SSID字符串// 预共享密钥// 安全类型// 网络ID// 优先级// 是否隐藏网络// 扫描信息结构 (wifi_scan_info.h)// SSID// BSSID (MAC地址)// 安全类型int rssi;// 信号强度// 频率// 信道宽度// 时间戳// 连接信息结构 (wifi_linked_info.h)

m0_67505153的博客 1060

Scala学习笔记20: Future 和Promise

在 Scala 中, `Future` 和 `Promise` 是用于处理异步操作的强大工具 ; 它们就像一对搭档, 协同工作, 优雅地管理着那些需要花费时间的任务 .

Taerge0110的博客 1204

YOLO11 锚框机制全解析:从改进 K-means 聚类到自适应优化,附多场景实战(附代码)

摘要 YOLO11的锚框机制采用"自适应、动态化、场景感知"的设计理念,通过数据驱动的锚框生成、多尺度感知分配和实时优化策略,显著提升目标检测性能。相较于早期YOLO版本,YOLO11的锚框完全基于训练集目标分布自适应生成,并引入智能分配策略,使不同尺寸目标获得最优匹配。技术架构包含自适应锚框生成、多尺度分配器和动态优化模块,通过改进的K-means聚类和交并比计算实现精准匹配。YOLO11锚框机制在检测精度、训练稳定性和场景适应性方面均有显著提升,为复杂场景下的目标检测提供更优解决方案

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 1322

使用Scala实现一个并发库(阻塞版本, 下一篇文章提供NonBlocking版本)

这个例子来源于scala圣经级教程《Functional Programming in Scala》,由于本人跟着书中的代码敲了一遍,然后写了点测试代码验证了一下正确性,所以就放在这做个备忘吧。贴出来只是为了方便自己,如果看不懂,但是又感兴趣的就去看原书吧…… &amp;amp;gt; 注:这个并发库使用的线程池如果只有唯一一条工作线程的话,会导致线程阻塞,可以参考main方法中的示例,阻塞原因与代...

lhever_的博客 331

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Scala中如何基于ZIO构建可组合的程序(命令行)

设计一个命令行程序 大多数命令行程序都是无状态的,这是理所当然的,因为它们可以很容易地集成到脚本中并通过shell管道链接。然而,对于本文,我们需要一个稍微复杂一点的程序。 让我们写一个SQL命令行程序。用户将通过文本命令与之交互,根据不同的SQL命令创建不同的程序命令以输出不同的字符,同时我们还希望可以循环输入。 对于这些问题中的每一个,我们将创建一个独立的模块,该模块依赖于其他模块,如下所示: 基本程序 ZIO 应用程序的基本构建块是ZIO[R, E, A]类型,它描述了有效的计算,其中: R 是运

梦境迷离 1076

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

netty5笔记-线程模型4-无锁队列MpscLinkedQueue

NioEventLoop里面使用了MpscLinkedQueue作为taskQueue,替换了父类中默认的LinkedBlockingQueue队列。taskQueue主要用于存放可执行任务,其调用的频率非常高,因此使用一个更高效的队列能带来很大的收益。 为什么在NioEvnetLoop里用MpscLinkedQueue替换了LinkedBlockingQueue,是使用了更好的算法?还是通过舍弃

youaremoon的专栏 6489

C语言冒泡排序法,无序数值实现升序或降序

冒泡排序: 一串无序数值,从第一个数值开始依次与后面的数字比较,交换位置,得到有序的数值(升序排列/降序排列),此过程成为冒泡排序。 冒泡排序法: 用冒泡排序,将无序数值转化位有序数值的方法,称为冒泡排序法。 运行效果: 升序排列 降序排列 实现以上功能: [代码+解释] 升序排列(小→大) int[] arr = { 1, 5, 6, 4, 5 ,0}; Console.WriteLine("冒泡排序后的数值:"); for (int i = 0; i < arr.Len

HuiDieDie的博客 6154

Scala 异步编程之 Future

同步异步,阻塞非阻塞,在IO模型中几个概念组合在一起不是很容易理解,但是只从代码执行的角度看同步异步是很清晰的: 同步代表这段代码中的逻辑必须执行完毕,而异步代表调用马上返回,但通常情况下是获取不到需要的值。 同步:val  value={ Thread.sleep(2000) 1 } 异步: val value=Future{ Thread.sleep(2000) 1 }

onwingsofsong的博客 8483

scala进阶:Future的理解及使用

看了下scala future的官方文档,融合了自己的理解整理在这里,例子全部来自官方文档:http://docs.scala-lang.org/overviews/core/futures.html future represents a result of an async method, would could due to long time-consuming operat

cykic的专栏 1万+

Netty源码分析---MpscLinkedQueue

 MpscLinkedQueue是netty自己实现的线程安全的队列,与JDK通过

凌霄的专栏 2473

Intrusive MPSC node-based queue

mpscq :Multiple-producer single-consumer lock free queue Advantages: + Intrusive. No need for additional internal nodes. + Wait-free and fast producers. One XCHG is maximum what one can get with mu...

maimang1001的专栏 383

原理剖析(第 012 篇)Netty之无锁队列MpscUnboundedArrayQueue原理分析

原理剖析(第 012 篇)Netty之无锁队列MpscUnboundedArrayQueue原理分析-一、大致介绍1、了解过netty原理的童鞋,其实应该知道工作线程组的每个子线程都维护了一个任务队列; 2、细心的童鞋会发现netty的队列是重写了队列的实现方法,覆盖了父类中的LinkedBlockingQueue队列,但是如今却换成了JCTools的一些并发队列,因为JCTools是一款对jdk并

YLIMH_HMILY的专栏 4048

BlockingQueue(阻塞队列)详解

注意:该随笔内容完全引自http://wsmajunfeng.iteye.com/blog/1629354,写的很好,非常感谢,复制过来算是个积累,怕以后找不到。 一. 前言   在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。本文详细介绍了Blo...

weixin_30478923的博客 2991

scala中一个高阶函数的N种调用方法

// (参数类型) => 结果类型 //定义接受一个函数参数的函数 def valueAtOneQuarter(f: (Double) => Double) = f(0.25) // 函数传参的完整写法 valueAtOneQuarter { (x: Double) => 3 * x } // scala类型推断写法 valueAtOneQua

NON blog 1469

scala的Future和Promise

前言 使用scala的Future和Promise就不得不提一下异步编程和多线程编程的区别。 共同点:异步和多线程两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性 不同点: 线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度。 多线程在单个线程中的处理程序依然是顺序执行,符合普通人的思维习...

齐梦星空 971

同时使用java和scala语言的maven项目pom文件示例

主要就是在pom.xml中添加scala的三个依赖包和maven-scala插件,配置如下:&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-in...

lhever_的博客 3157
上一篇: 使用Scala实现一个并发库(阻塞版本, 下一篇文章提供NonBlocking版本)
下一篇: 使用Scala实现一个基于性质的测试库
lhever_
博客等级 码龄14年 213粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值