这篇文章只是简单使用java concurrent库写了个二维数组运算,并无什么实际意义和技术可言,请仅把我当做标题党。更有价值的东西来自于后面的留言。
最近正被项目的并发问题搞得焦头烂额,在封装的语义和项目需求上似乎都出现了问题,迟迟实现不了。昨天无意中看到这个招聘题,挺有意思的。出题人的本意可能是想考考时下流行的并行运算,受限于CPU,在PC上这种纯运算的效果并不明显,但并发倒是以后的一种趋势…
- 使用Java多线程实现下述算法:
输入:整数组成的m*n的矩阵A。(m=100000, n=10000)
输出:一个数列B,数列B中的每一项为矩阵A中对应列数字之和
CPU的核心是越来越多了,以后并行运算是一种趋势,越来越多的程序需要考虑使用并行运算来加速,硬件厂商给了我们翻倍的CPU,而不是翻倍的速度,真麻烦
……
首先定义一个类,就叫做MatrixSolver吧
package fyting.javaeye.com; public class MatrixSolver { private final int[][] matrix; private final int maxThreads; private final Map<Integer, Integer> results = Collections.synchronizedMap(new TreeMap<Integer, Integer>()); public void start(){ //… } }
写一个main方法来测试:
public static void main(String[] args) { final int row = 5000, column = 2000; final int[][] data = new int[row][column]; for(int i = 0 ; i < row; i++) { for(int j = 0; j < column; j++) { data[i][j] = j; } } final int maxThreads = 3; MatrixSolver solver = new MatrixSolver(maxThreads, data); solver.start(); }
然后是实现的代码,利用JDK5的线程池,可以很轻松实现:
(事实上,JDK里CyclicBarrier的javadoc就是一个解矩阵的例子)
public void start() { ExecutorService executor = Executors.newFixedThreadPool(maxThreads); final long st = System.nanoTime(); if(this.matrix.length == 0) { System.err.println("no matrix data!"); return; } final int columnCount = this.matrix[0].length; //创建一个计数的latch,用来等待运算结果 final CountDownLatch latch = new CountDownLatch(columnCount); for(int i = 0 ; i < columnCount; i++) { final int column = i; executor.execute(newTask(column,latch)); } try { latch.await();//等待运算完毕,否则会一直wait在这里 executor.shutdown(); long et = System.nanoTime(); long time = (et - st) / (1000*1000); System.out.println("success, time: " + time + "ms"); executor.awaitTermination(1, TimeUnit.SECONDS); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println("maxtrix: " + (matrix.length + "*" + matrix[0].length)); System.out.println("column0==>" + ArrayUtils.toString(matrix[0])); System.out.println("results==>" + results); } protected Runnable newTask(int column, CountDownLatch latch) { return new ColumnSolver(column,latch); } private class ColumnSolver extends Thread { private final int columnIndex; private final CountDownLatch latch; ColumnSolver(int columnIndex, CountDownLatch latch) { this.columnIndex = columnIndex; this.latch = latch; } @Override public void run() { int count = 0; for(int j = 0, rowCount = matrix.length; j < rowCount; j++) { count += matrix[j][columnIndex]; } results.put(columnIndex, count); latch.countDown();//计数器减1 } }
当然,如果是JDK1.4,可以用单独的Doug Lea大师写的java concurrent包,否则需要自己实现线程池了,很麻烦。如附件中的代码,很容易出错,实在是没有必要在项目中采用。
曾经想努力搞懂啥叫SOA,因为某著名杂志曾写到21世纪不懂SOA的软件开发人员无法生存。结果,我真的太肤浅,看来看去,技术上的东西就那几种,也远远达不到各方所宣传的效果,只是对原有的经验的一个总结和标准化。所以,看上去的SOA就什么都是,它是一种架构,是一种解决了N多问题的方案,一种设计理念,一种软件的构建方法,它,还可以是一种或多种产品……
还别说,架构、方案,让一群不太懂技术的经理们信以为真,于是,赶快跟上。所谓的理念、设计之类的名词也把一群软件开发人员忽悠了,好久不来JE,发现一个SOA的帖子只因为你不懂SOA,我本以为可以解除我的困惑,结果楼主高屋建瓴之后来了段代码:
public class CalculatorService { private AddService addService; @Reference public void setAddService(AddService addService) { this.addService = addService; } public double add(double n1, double n2) { return addService.add(n1, n2); } }
并且说到:那么,addService.add(n1, n2)是什么调用?在SCA的架构体系下:
- 他可以是简单的java调用——你能方便而快速的做JUnit Test.
- 他可以也可是复杂一点的EJB调用——事务,分布式,Cache等你所想要的企业级特性的支持
- 他还可以是复杂一点的Web Service调用,具体提供这个add服务的也许是一个.Net程序,又或者是一个八百年前的老系统已有的服务。。。。
是的,他可以做最复杂的事情,但也是最简单的POJO。对于开发者来说,只用关心他的业务,其它的一切都可以忽略。
你看出什么来没有,这代码似曾相识啊,这就是一标准的策略模式的实现。不要一提设计模式就露出一副鄙视的样子,好吧,这不是Spring里多年前的IOC啊、DI啊啥的?你看,这还真能忽悠。(这也挺搞的,以前很多人搞设计模式,结果自己把自己忽悠了。现在搞SOA,又有人把自己忽悠了,而且被设计模式给忽悠了)
SOA,至少是现在我自己了解到的SOA,就是个把各种东西揉在一起,换个马甲,然后开始卖概念,顺便把产品也送出去。这也不要技术人员懂,就是卖给IT经理之类的(记得是O6z大叔这么说的?)。从技术的角度提出,然后让技术人员看不懂,却给不搞具体技术的人看,然后得出某种极其先进、深不可测、变幻万千的结论,真是……
上次某厂商来成都时我专门去听了,我承认浪费了半天时间。其中有个印象比较深刻的:
提到这个厂商能做到与IBM、BEA之流一起制定标准,实属不易。但人家也从不亲口提民族产业,人家只说合作。到最后不知道是有人被忽悠了还是咋的,在提问时说道:以后SOA会分为微软阵营和其他厂商阵营,还举例使用WCF的例子,说这就被绑定了,用WCF就被绑上微软了。微软自然是人人喊打的,于是最终演变为一场支持国产软件的活动,为民族软件而自豪,这是有人亲自发短信,在现场的短信大屏幕上出现的。我问道:用那啥SOS就不绑定了吗?无解。
我问那个Component是怎么划分的粒度,我想看看这和普通的软件开发流程有啥区别,如何应对变化。得,最后演示了个画图生成代码的高级工具,但没看出太多实质的东西,发生变化就得重新画图,复杂的流程估计那图得成蜘蛛网了,比代码看起还累。不过效果倒是很震撼。看:只懂业务也能写软件了,正符合被忽悠人群的需要。这东西,本来就一高级代码生成器+文档、流程管理(据说这一点还算不错),扯上SOA,值钱了,也好卖了,一份抵过去五份。我并非想批判人家的产品,只是想让大家看看这现实中的SOA是怎么回事。
一时兴起,言辞太偏激,本来想作为回帖的,但还是贴到个人博客上比较好,好久没打这么多字了,正好凑一篇。:)
到处写blog真是累,幸好有windows live writer和一堆插件,微软的window-live总算做出个有用的东西……
虽说代码行数不重要,但有时候总想统计下自己的代码行数,看看最近的成果。以前一直用这个国产小软件,但感觉操作稍显烦琐,我更喜欢命令行的方式,自由度更高。昨天无意中在这里发现了叫做CLOC的小软件,基于Perl,并且是Opensource的,地址http://cloc.sourceforge.net/。下载后只有一个cloc.exe文件,使用方式也很简单,只需要:cloc.exe /path/to/source-code,输出如下
C:\Documents and Settings\kenny>cloc D:\Projects\myproject\
900 text files.
classified 900 files
634 unique files.
607 files ignored.
http://cloc.sourceforge.net v 1.04 T=3.0 s (84.3 files/s, 11367.0 lines/s)
——————————————————————————-
Language files blank comment code scale 3rd gen. equiv
——————————————————————————-
Java 135 1778 1963 8779 x 1.36 = 11939.44
Javascript 22 1875 1761 8590 x 1.48 = 12713.20
XML 39 308 247 2744 x 1.90 = 5213.60
HTML 39 33 474 2000 x 1.90 = 3800.00
CSS 11 156 72 1445 x 1.00 = 1445.00
DTD 1 234 254 713 x 1.90 = 1354.70
SQL 2 42 44 406 x 2.29 = 929.74
JSP 3 18 14 106 x 1.48 = 156.88
XSLT 1 0 6 39 x 1.90 = 74.10
——————————————————————————-
SUM: 253 4444 4835 24822 x 1.52 = 37626.66
——————————————————————————-
当然了,有很多选项可以用,具体的可以看看cloc首页的介绍。当然,每次这样手动输入命令很麻烦,考虑下和Total-Commander结合。编辑一个cloc.bat文件,内容如下:
cloc.exe %1 PAUSE
把这个bat文件拖到TC的工具栏上
然后在工具栏新出现的图标上点右键,选“更改”,然后把参数设置为%p,如图:
“确定”后大功告成,在TC里进入你的源码目录时,点击刚才新建的图标,就开始自动统计当前目录了。
MySQL负责开源社区的副总裁Kaj Arnö在blog中写道:MySQL今后将继续保持所有功能的开源,包括MySQL Connectors、存储引擎,以及MySQL6.0中新增的备份功能、MyISAM备份驱动、加密和压缩存储也将开源。
在blog中,Kaj Arnö提到,做出此决定是因为MySQL已经从当初想独立上市的路线转换出来,变成了SUN的一部分。他还提到了MySQL的两条发展路线:openness, and the business model.
原文见 http://blogs.mysql.com/kaj/2008/05/06/mysql-server-is-open-source-even-backup-extensions/
原作者 Kenny,转载请注明出自 http://www.fyting.com,非常感谢。
dojo1.1发布也有些时日了,今天静下来看了看到底有哪些更新以及对项目的影响,顺便把release notes大体翻译了过来。
Core
dojo.fromJson解析失败时,会抛出error,需要程序员手动try、catch
var result = text; try{ result = dojo.fromJson(text); }catch(e){ // squelch exception, use input as result }
多版本支持
dojo1.1可以与其他版本的dojo共存,甚至可以修改dojo的库名称,详细见:Dojo Book Page on multiversion support
在DOM载入后再加载dojo
设置djConfig.afterOnLoad = true,这是测试页面 没感觉到这个功能的用处,并且在DOM载入后如果移动鼠标有可能引起javascript,整个dojo都无法载入。
XMLHttpRequest的变化
以前那一堆dojo.xhrGet(), dojo.xhrPost(), dojo.xhrRawPost(), dojo.xhrPut(), dojo.xhrRawPut() 还有 dojo.xhrDelete(),现在终于有了一个通用的函数:dojo.xhr()。
使用dojo.xhr*将发送名为“X-Requested-With”的http header,值为“XMLHttpRequest”
cacheBust
如果设置djConfig.cacheBust = (new Date()).getTime(),载入模块和模板时,将把这个cacheBust的值将添加到URL中,防止浏览器缓存。在1.0里面其实已经存在,也是个不知所云的功能。
dojo.attr()
新增加dojo.attr(),dojo.hasAttr(),还有dojo.removeAttr()函数,用于获取DOM节点的attribute
var d1 = dojo.byId('div1'); console.debug(dojo.attr(d1,"id")); console.debug("div1 has age?" + dojo.hasAttr(d1,"age")); dojo.attr(d1,"age",18); console.debug("div1 has age?" + dojo.hasAttr(d1,"age")); console.debug(dojo.attr(d1,"age"));
dojo.style()
dojo.style现在可以一次性设置多个css属性,以前是这样的:
dojo.style(dojo.byId('div2'),"width","700px;"); dojo.style(dojo.byId('div2'),"height","600px;");
现在可以这样了:
dojo.style(dojo.byId('div2'),{ width:"700px", height:"600px", background:"#ccf" });
dojo.query/NodeList
dojo.query()结果可以使用attr()、instantiate(),还有之前就可以使用的style()也可以使用上面的那种dojo.style()的用法了。
dojo.style("thinger", { "opacity": 0.5, "border": "3px solid black", "height": 300 });
动画/animation
修正了动画效果的性能问题,增加了一个新的dojo.anim()方法,默认的duration从1秒变成了350ms,简化了指定动画属性的语法。另外重写了dojo.fx.combine()和dojo.fx.chain()的集成,现在集成不同的动画效果更加简单。
dojo.anim("id", { opacity: 0 }, 1000);
Adobe AIR的支持
1.1里面dojo提供了更好的AIR支持。http://www.dojotoolkit.org/air
以前的文章了,先转过来凑数,以后将只在这里更新~~~
原作者: Kenny 转载请注明出自 http://www.fyting.com,谢谢
2006年初,dojo还是0.22的时候就很关注它的发展,可一直没有在实际项目中使用。一来是由于文档的缺少,而来是dojo的相关介绍总是让人望而生畏。到现在都如此,第一个hello world就搞了一大堆东西,比如widget组件,自定义的script标签等,加上要引入什么css文件,djConfig、dojo.require等等,让人很迷惑,这么复杂,到底dojo该怎么使用呢?我只是想把dojo当作一个普通的js类库,就像prototype那样?OK,闲话少说,来看看如何使用dojo。
首先,引入dojo.js
dojo的发行包里有4个子目录
假设你是这样的目录结构:
project
|
+–dojo-lib
| |
| +–dijit
| +–dojo
| +–dojox
| +–util
|
+–dojo_hello_world.html
要引入的文件是名叫”dojo”的子目录里的dojo.js
<script type="text/javascript" src="./dojo-lib/dojo/dojo.js"> </script>
开始使用dojo
现在开始使用dojo的第一个函数:dojo.byId
dojo.byId就等同于常用的document.getElementById
<input type="text" name="username" id="username" value="Mark" />
<script type="text/javascript">
var username = dojo.byId('username').value
alert(username);
</script>OK,是不是和普通的js库一样,没有任何玄机?
dojo.addOnLoad
现在我们想在window.onload里面处理一点东西,就像Ext.onReady,这个东西在dojo里叫做dojo.addOnLoad
dojo.addOnLoad(function(){ var username = dojo.byId('username').value alert(username); });
dojo.connect
OK,window.onload搞定了,那么如何监听普通的dom事件呢?没问题,强大的dojo.connect出场
<script type="text/javascript">
function sayHello(event)
{
alert("Hello");
}
dojo.addOnLoad(function(){
var btn = dojo.byId('hello');
dojo.connect(btn,"onclick",sayHello);
});
</script>
<input type="button" id="hello" value="Hello" />是不是和prototype的Event.observe($(’btnAdd’), “load”, doAdd)差不多?
用prototype时最烦的就是那个长长的bindAsListener了,使用dojo.conncect,可以在第三个参数中指定当前的scope:
var name = "Mark" function sayHello() { alert("Hello " + this.name); } var obj = { name: "Karl" } dojo.addOnLoad(function(){ var btn = dojo.byId('hello'); dojo.connect(btn,"onclick",obj,sayHello);//注意这行的第三个和第四个参数 });
OK,点击按钮,将输出:Hello Karl
这里dojo.connect的第三个参数变成了scope,而handler函数是第四个,实际上
dojo.connect(btn,”onclick”,sayHello);
与
dojo.connect(btn,”onclick”,null,sayHello);
相同。
更加复杂的用法这里不作介绍,写太多就越搞越复杂了,后面再写文章详细介绍dojo.connect,这里只简单介绍如何绑定DOM事件。
xmlhttp dojo.xhrGet
OK,介绍了简单的DOM操作方法,接下来该到Ajax的传统项目-XmlHttp了
在使用xmlhttp时,需要注意到编码的问题,要让dojo默认绑定为utf-8怎么办呢?很简单,只需要修改一下引入dojo.js时的标签:
阅读全文…