- 浏览: 423332 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (118)
- JBPM4 (1)
- JavaScript (11)
- Hibernate (3)
- Spring (2)
- JAVA设计模式 (0)
- JAVA基础 (8)
- JQuery (1)
- Maven (9)
- Ant (1)
- Log (3)
- Linux (13)
- NoSQL (1)
- Emacs (6)
- JAVA (10)
- 道,可道,非常道 (6)
- CSS3 (3)
- HTML5 (1)
- 其他 (3)
- groovy (1)
- Clojure (21)
- ExtJs (3)
- play! (3)
- freemarker (1)
- prolog (3)
- python (2)
- hadoop (1)
- OS X (1)
- JVM (1)
- scala (3)
- 算法 (2)
- play2 (0)
- play2 scala (1)
- play2 java (1)
- android (0)
- xxx (0)
- storm (0)
- go (0)
最新评论
-
yhxf_ie:
Scala真好玩啊
关于scala搞出的新概念和语法糖 -
莴笋的春天:
能解密吗?
MD5算法的一个实现 -
TerrorM-eye:
引用神奇的花括号{}代替小括号()语法那个让我想起了spark ...
关于scala搞出的新概念和语法糖 -
u012896872:
不错,有收获。
关于scala搞出的新概念和语法糖 -
qiaoxiaoka:
我在logback中加了 <logger nam ...
在logback中配置mybatis显示sql
转载地址:http://www.ibm.com/developerworks/cn/web/wa-clojure/index.html?ca=drs-
1、本地线程var。
注意,这里的操作需要用到绑定宏。这改变了 var 的线程本地值。
因此,在 place-offer 函数的执行范围内 droid 和 history 所指向的值将不同。
然而,在执行之外,该值没有变化。要记得,默认情况下在 Clojure 中所有事物都是不可变的(immutable)。
绑定 vars 允许在线程本地范围内对事物进行变更。如果任何其他线程想要读取该值,将看不到任何变化。
对于仅需要改变状态并将其作为执行离散任务的一部分时,这是完成任务的简单方法。如果想以其他线程可见的方式来变更状态,可能需要采用 Clojure 的 atoms。
2、简单同步atom
atom 是状态可变更的变量。其使用非常简单并且完全同步。换句话说,
如果调用了改变 atom 值的函数,那么当该函数结果返回时, 可以确保所有的线程都能看到新值。
3、ref的软事务处理
Clojure 的 refs 提供了其最强大的并发特色。那就是 Clojure 的 Software Transactional Memory (STM) 实现。
Refs 与 atoms 类似。与 atoms 对比,它通常只需要一行额外的代码,其主要优势是协调。
利用 refs,可在单个事务中改变多个对象的状态。该事务将具有原子性、一致性、并与 ACID 的 ACI 隔离(由于全在内存中,因此不具有持久性)。
这一隔离属性意味着任何观察者将会要么见到事务中的所有变更,要么一个也见不到。atoms 不会出现这种情况。
Refs 遵循与 atoms 相同的包装模式。place-offer 函数的执行从调用 dosync 开始。此函数包装一个事务。
它提供前面所提到的协调。它允许同时改变 droid 和 history,并了解不会有任何对数据的直接读取。
如同 atoms 一样,您可以取消引用,并在执行完函数后打印该值,验证该值已经改变。
(关于函数的副作用 :函数副作用有两种原因:
1、在函数过程体内出现了改变非函数局部变量的语句,使得函数的运行能够改变全局变量的值。
2、函数体内有转出函数体的过渡语句,常见的就是GOTO语句。
函数副作用的表现:设x是一个函数F的非局部变量,在函数体内,x值能够被改变。
故,对于x*F来讲,不满足交换律,即x*F=F*x不一定成立(不排除特殊成立的情况),这就能够产生许多问题)
此时,您可能想知道 STM 在此处到底是如何工作的。如果一个线程利用数量 25 来调用 place-offer 函数,
同时,另一个线程利用数量 22 调用同一函数,将会发生什么情况?
Clojure 会确保在事务中间该值没有发生改变,因此,如果事务到达了 dosync 块的结尾,
并且,STM 可看到在当前事务启动以来有另一事务已经完成了,那么当前事务将回滚并再次运行。
这使得,仅纯函数 —— 也就是不具有副作用的函数 —— 才能作为事务的一部分,因为函数可能将被运行多次。
Clojure 采用性能非常高的永久数据结构,来确保此类事务/回滚的效率。
(同步函数:执行后等待响应再继续执行下面代码.,
异步函数:执行后不等待响应就能继续执行下面代码)
Refs 和 atoms 都是同步函数。如果不必同步变更状态,那么,agents 将提供一些优势。
4、简单异步agents
您经常需要变更状态,但是不必等待其变更,或者如果可对多个线程进行变更时,不必关心其变更的顺序。
这是个通用的模式,并且 Clojure 提供了编程模型来予以解决:agents
1、本地线程var。
注意,这里的操作需要用到绑定宏。这改变了 var 的线程本地值。
因此,在 place-offer 函数的执行范围内 droid 和 history 所指向的值将不同。
然而,在执行之外,该值没有变化。要记得,默认情况下在 Clojure 中所有事物都是不可变的(immutable)。
绑定 vars 允许在线程本地范围内对事物进行变更。如果任何其他线程想要读取该值,将看不到任何变化。
对于仅需要改变状态并将其作为执行离散任务的一部分时,这是完成任务的简单方法。如果想以其他线程可见的方式来变更状态,可能需要采用 Clojure 的 atoms。
user=> (defstruct item :title :current-price) #'user/item user=> (defstruct bid :user :amount) #'user/bid user=> (def history ()) #'user/history user=> (def droid (struct item "Droid X" 0)) #'user/droid user=> (defn place-offer [offer] (binding [history (cons offer history) droid (assoc droid :current-price (get offer :amount))] (println droid history))) #'user/place-offer user=> (place-offer {:user "Anthony" :amount 10}) {:title Droid X, :current-price 10} ({:user Anthony, :amount 10}) nil user=> (println droid) ;这里可以看出droid的值并没有被改变。 {:title Droid X, :current-price 0} nil
2、简单同步atom
atom 是状态可变更的变量。其使用非常简单并且完全同步。换句话说,
如果调用了改变 atom 值的函数,那么当该函数结果返回时, 可以确保所有的线程都能看到新值。
user=> (def droid (atom (struct item "Droid X" 0))) #'user/droid user=> (def history (atom ())) #'user/history user=> (defn place-offer [offer] (reset! droid (assoc @droid :current-price (get offer :amount)))) #'user/place-offer user=> (place-offer {:user "Anthony" :amount 10}) {:title "Droid X", :current-price 10} user=> (println @droid) ;;这里算是另一个线程调用查看droid的状态 {:title Droid X, :current-price 10} nil
3、ref的软事务处理
Clojure 的 refs 提供了其最强大的并发特色。那就是 Clojure 的 Software Transactional Memory (STM) 实现。
Refs 与 atoms 类似。与 atoms 对比,它通常只需要一行额外的代码,其主要优势是协调。
利用 refs,可在单个事务中改变多个对象的状态。该事务将具有原子性、一致性、并与 ACID 的 ACI 隔离(由于全在内存中,因此不具有持久性)。
这一隔离属性意味着任何观察者将会要么见到事务中的所有变更,要么一个也见不到。atoms 不会出现这种情况。
user=> (def droid (ref (struct item "Droid X" 0))) #'user/droid user=> (def history (ref ())) #'user/history user=> (defn place-offer [offer] (dosync (ref-set droid (assoc @droid :current-price (get offer :amount))) (ref-set history (cons offer @history)) )) user=> (place-offer {:user "Tony" :amount 22}) ({:user "Tony", :amount 22}) user=> (println @droid @history) {:title Droid X, :current-price 22} ({:user Tony, :amount 22}) nil
Refs 遵循与 atoms 相同的包装模式。place-offer 函数的执行从调用 dosync 开始。此函数包装一个事务。
它提供前面所提到的协调。它允许同时改变 droid 和 history,并了解不会有任何对数据的直接读取。
如同 atoms 一样,您可以取消引用,并在执行完函数后打印该值,验证该值已经改变。
(关于函数的副作用 :函数副作用有两种原因:
1、在函数过程体内出现了改变非函数局部变量的语句,使得函数的运行能够改变全局变量的值。
2、函数体内有转出函数体的过渡语句,常见的就是GOTO语句。
函数副作用的表现:设x是一个函数F的非局部变量,在函数体内,x值能够被改变。
故,对于x*F来讲,不满足交换律,即x*F=F*x不一定成立(不排除特殊成立的情况),这就能够产生许多问题)
此时,您可能想知道 STM 在此处到底是如何工作的。如果一个线程利用数量 25 来调用 place-offer 函数,
同时,另一个线程利用数量 22 调用同一函数,将会发生什么情况?
Clojure 会确保在事务中间该值没有发生改变,因此,如果事务到达了 dosync 块的结尾,
并且,STM 可看到在当前事务启动以来有另一事务已经完成了,那么当前事务将回滚并再次运行。
这使得,仅纯函数 —— 也就是不具有副作用的函数 —— 才能作为事务的一部分,因为函数可能将被运行多次。
Clojure 采用性能非常高的永久数据结构,来确保此类事务/回滚的效率。
(同步函数:执行后等待响应再继续执行下面代码.,
异步函数:执行后不等待响应就能继续执行下面代码)
Refs 和 atoms 都是同步函数。如果不必同步变更状态,那么,agents 将提供一些优势。
4、简单异步agents
您经常需要变更状态,但是不必等待其变更,或者如果可对多个线程进行变更时,不必关心其变更的顺序。
这是个通用的模式,并且 Clojure 提供了编程模型来予以解决:agents
user=> (def history (agent ())) #'user/history user=> (def droid (agent (struct item "Droid X" 0))) #'user/droid nil user=> (defn place-offer [offer] (send droid #(assoc % :current-price (get offer :amount)))) user=> (place-offer {:user "Tony" :amount 33}) #<Agent@396477d9: {:title "Droid X", :current-price 0}> user=> (await droid) nil user=> (println @droid) {:title Droid X, :current-price 33} nil
发表评论
-
地图着色——core.logic求解
2015-06-16 13:24 1029记得很久很久之前写过一篇《七周七语言——地图着色》。用core ... -
storm源码阅读——启动脚本一览
2014-12-22 01:29 0testtestst -
storm源码阅读——Nimubs启动
2014-12-12 18:29 0学习使用clojure代码也有一段时间了。除了用clojure ... -
用clojure实现一致性哈希算法(consistent hashing)
2014-05-16 18:42 1447一、依赖的jar包 [com.google.guava/g ... -
关于clojure的gen-class
2014-05-15 12:04 2055关于gen-class的参数说明: :name aname ... -
关于clojure的ns中的require,use,import等
2014-05-15 11:20 2917初学clojure的时候曾经对ns引入库的几个函数疑惑了一阵, ... -
clojure逻辑编程框架——core.logic入门
2014-03-10 00:31 1625core.logic是miniKanren的一个实现。mini ... -
用clojure和javascript看hadoop的map和reduce
2014-01-16 18:28 0(reduce + (map #(* % 2) [1, ... -
lein插件大全
2014-01-08 22:54 3733lein插件的wiki地址:https://github. ... -
什么是闭包
2013-12-26 22:11 87今天有个同事问我什么是闭包? 我脑子里一闪而过匿名函数,内部访 ... -
一张clojure思维导图
2013-12-25 10:19 1073... -
clojure网页爬虫代码阅读
2013-09-10 18:34 0clojure网页爬虫代码: (ns examples.c ... -
一步完成emacs的clojure开发环境配置——emacs-live
2013-08-26 15:49 1876断断续续学习Emacs好久 ... -
clojure解构(clojure destructuring)
2013-06-15 02:17 3866解构是什么? 可以认为map、list、struct等是构造出 ... -
clojure defn的参数解构
2013-04-16 23:50 1883In Clojure 1.2, you can destr ... -
clojure学习——通过ssh2协议远程执行命令
2013-02-19 16:06 8一、添加ganymed-ssh2依赖 (defprojec ... -
Clojure学习——Web框架Noir
2012-12-16 12:25 1861Noir是一个clojure的轻量级的web快速开发框架。而且 ... -
Clojure学习——Protocols & Datatypes
2012-12-08 17:37 0由于java的接口有一定的缺憾,所以 -
Clojure学习——给持久化框架配上c3p0连接池
2012-12-06 17:07 1768之前的两个持久化框架都没有使用连接池。总感觉不放心。试着配置了 ... -
Clojure学习——持久化框架clj-record
2012-12-06 10:47 1575clj-record是仿Ruby on Rails Activ ...
相关推荐
在现代编程实践中,多核处理器的普及使得并发编程成为了提升程序性能的关键。Clojure,作为一种现代的Lisp方言...Clojure的并发模型不仅提高了程序的性能,还通过减少锁的使用和简化状态管理来提高了代码的可维护性 。
引用是Clojure并发模型的核心,它代表了一个变量的身份,而这个身份随着时间的推移可以指向不同的不可变值。引用允许观察者(如其他函数或用户界面组件)查看其当前指向的值,而无需担心同步问题。例如,一个数据库...
Avout 为 Clojure 的内存 state 模型带来分布式应用发布,通过提供一个分布式实现的 Clojure's Multiversion Concurrency Control (MVCC) STM ,相当于分布式、持久性和可扩展的 Clojure's Atom and Ref 并发原语。...
Clojure是一种基于Lisp的函数式编程语言,它运行在Java虚拟机(JVM)上,具有强大的并发处理能力和丰富的库支持。 首先,《Clojure Programming》是一本全面介绍Clojure语言的指南,由Chas Emerick、Crispin Cowan...
在并发处理方面,Clojure采用软件事务内存(Software Transactional Memory, STM)机制,提供了一种声明式的处理方式,让开发者可以编写无锁并发代码,降低了并发编程的复杂性和出错概率。 Clojure的`core.async`库...
4. **Concurrency**: Clojure提供了一种更为安全和高效的并发模型——软件事务内存(STM),避免了传统锁机制所带来的问题。 5. **Java Integration**: Clojure与Java之间的调用十分直接,无需经过任何转换层,这...
- **并发编程**:深入探讨 Clojure 的并发模型,如原子、引用、代理和通道等。 - **社区资源和工具**:列出了一系列 Clojure 社区提供的工具和库,以及如何参与开源贡献的方法。 #### 四、本书适用人群 - **数据...
- **软件事务内存(STM)**: Clojure通过STM机制实现了高度并发的编程模型,它允许开发者以事务的方式更新共享状态,从而简化了并发编程的复杂度。 #### 六、学习资源与社区 - **官方文档**: Clojure官方网站提供了...
- **事务内存(STM)**:Clojure提供了一种基于软件事务的并发模型,可以简化并发编程的难度。 #### 八、社区与资源 - **社区支持**:Clojure有一个活跃的社区,可以通过邮件列表、论坛、会议等多种途径获取帮助和...
4. **并发模型**:Clojure提供了强大的并发编程模型,包括原子、引用和代理等概念,这些特性使得Clojure非常适合构建高并发系统。 5. **元编程**:Clojure具有丰富的元编程能力,可以通过宏(macros)等机制自动生成...
3. **内存安全的并发模型**:Clojure 使用软件事务内存(Software Transactional Memory, STM)系统,使得并发编程变得简单而安全,避免了常见的线程安全问题。 4. **函数式编程**:Clojure 鼓励使用纯函数和不可变...
4. **高效的并发模型**:Clojure提供了一种称为“软件事务内存”(Software Transactional Memory, STM)的机制,可以简化并发编程的复杂度。 5. **动态类型**:Clojure是一种动态类型的语言,这意味着变量可以在...
理解这些机制的工作原理,以及如何使用 `dosync` 和 `alter` 等命令来管理状态变更,是掌握Clojure并发的关键。 5. **REPL(Read-Eval-Print Loop)**:Clojure 的交互式开发环境(REPL)是其开发流程的核心部分。...
- **第5章:并发编程** - 详细介绍 Clojure 中的并发模型和工具,包括原子变量、引用、代理等。 - **第6章:面向对象编程** - 虽然 Clojure 主要是一种函数式语言,但也支持面向对象编程,本章将介绍如何在 Clojure ...