2009年8月7日星期五

Ophone开发者网站忘记了android

Ophone是中国移动“自主研发”的手机操作系统,最近刚公布了开发者网站http://www.ophonesdn.com

为什么自主研发四个字上面有引号呢?这个ophone实际上是从Google的Android手机操作系统上修改和二次开发而来的,并非原创。完全开放源代码的Android系统给ophone打下了一个重要的基础,从设计结构上来说,ophone只是android的一个修改版。站在巨人的肩膀上是一个好事情,但是站都站了,却连师傅的名字都不肯提,偏要摆出一副自主创新开天辟地的架势,这就不好了。ophone完全可以说自己是“基于Google Android系统二次开发,符合中国移动的具体需求”,相信也不会给自己丢脸。

抛开这些事情不说,ophone还是有点前途的,前提是中国移动能够搞出合理的上网资费套餐,并且经营好应用程序商店(Mobile Market)。用户用的起,敢用了,就会带动应用程序的销售;应用程序真正有销量,就会激励开发者绞尽脑汁地制作更好的程序;有更多好的应用程序,方便了用户的生活,用户就会更依赖3G网络。这个共赢的环节逐个打通,中国移动的发财日子就不远了。

最后,我也注册了一个ophone开发者帐号,有空体验一下 :)

p.s. 中国移动怎么就把mac版本的sdk生生阉割掉了呢?tnn的。

2009年8月5日星期三

Packing all-in-one JAR for Hadoop (HadoopJar)

Hadoop allows us to pack our code into a jar file and run it with "hadoop jar mycode.jar". However, if our code depends on other jars (most non-trival codes do), distributing those depdendency jars becomes a problem.

Here I introduce one approach used by myself, which packs our own code and dependency jars into one jar. This all-in-one jar can be run using "hadoop jar my-all-in-one.jar", and all dependencies will work with no problem. I name this solution as HadoopJar.

I use an Ant task to do this. The XML code snippet is as follows,
<target name="hadoop-jar" depends="compile" description="Create binary distribution">
<!-- Firstly, copy all dependency jars into build/lib, while build is the root folder for the future jar. -->
<copy todir="${path.build.classes}/lib">
<fileset dir="lib">
<include name="**/*.jar">
<!-- We exclude hadoop-*-core.jar because it's already in the hadoop classpath -->
<exclude name="**/hadoop-*-core.jar">
</exclude>
</include>

<!-- Combine all dependency jars' names to a string, which can be used as a CLASSPATH value -->
<pathconvert property="hadoop-jar.classpath" pathsep=" ">
<regexpmapper from="^(.*)/lib/(.*\.jar)$" to="lib/\2" />
<path>
<fileset dir="${path.build.classes}/lib">
<include name="**/*.jar" />
</fileset>
</path>

<!-- Generate a manifest file contains the previous made CLASSPATH string -->
<manifest file="MANIFEST.MF">
<attribute name="Class-Path" value="${hadoop-jar.classpath}" />
<!-- Set a default entry point -->
<attribute name="Main-Class" value="org.nogroup.Main" />
</manifest>

<!-- Pack everything into one HadoopJar -->
<jar basedir="${path.build.classes}" manifest="MANIFEST.MF" jarfile="${path.build}/learning-hadoop.jar">
<include name="**/*.class">
<include name="**/*.jar">
</include>

<!-- Delete the manifest file -->
<delete dir="${path.build.classes}/lib" />
<delete file="MANIFEST.MF" />

</target>


We are done :). I tried this on our hadoop-0.15.0 cluster with 6 machines, and it also works in higher version of Hadoop, including hadoop in local-mode.

Hope this helps.

p.s. Dependency jars, also called third-party jars, third-party library.
I also wrote a Chinese version at here.

2009年7月11日星期六

我不远万里翻过伟大的墙来说句话

真是不容易啊,好久都没登上自己的博客了。我遵纪守法,从不谈论那啥那啥,咋就稀里糊涂地被绿伟大的坝墙了呢?

2009年5月18日星期一

Job Opening: Google Beijing Research

Job Title

Senior Research Scientist

Job Description

Google Beijing Research is looking for two highly motivated senior scientists to research and develop distributed machine learning algorithms for Web-scale applications such as search relevance, classification, recommendations, advertisement, and user research. Beijing Research has been collaborating with scientists and research interns from top universities world-wide including MIT, UC, Tsinghua, PKU, and etc. The position will be at Google Beijing office, which is located at Tsinghua Science Park. Among several, a couple OpenSource algorithms developed by Beijing Research are available at:

· Parallel SVMs (PSVM);

· Parallel LDA (PLDA)

Qualifications:


1. PhD in Compute Science, Mathematics, Statistics, or related areas with 3-5 years experience.

2. Strong publication track record at top refereed conferences.

3. Strong motivation to work with large-scale real-life data mining applications in team environment.
4. Perseverance, focus, integrity, ability to make things done, leadership in organization and partnership and communication with teams in the US.
5. Proven knowledge in Machine Learning, Data Mining, Natural Language Processing, Numeric Analysis, and/or Optimization.


有兴趣的联系我,哈哈

2009年5月12日星期二

2009年5月10日星期日

富家子弟飙车撞死路人却无动于衷,良心都被狗吃了

发信人: NoLost (不再沉迷), 信区: NewExpress
标 题: 全国同胞,浙籍人士,浙大校友团结起来,据理力争
发信站: 水木社区 (Sat May 9 00:28:31 2009), 站内

也许今天,无良的“富二代”飙车族撞死的只是一个普通的谭卓,但是明天也许
就会是身边的他、她、甚至是我们自己。如果今天我们不为谭卓据理力争,施加舆论
压力,那么明天我们至亲、好友也可能死不瞑目。

飙车俱乐部成员胡某,爱好是飙车、改装车、炫富,无正经职业。杭州师范学院
体育系学生,杭州江干区人,改装跑车车牌浙A.608Z0。曾经因为屡次在交通高峰路
段“漂移”被警方警告,但是屡教不改,昨晚将位于斑马线上的受害者撞高至5米高
处,在空中翻滚若干个来回后跌落惨死。目前杭州警方召开了新闻发布会,但是对于
初步调查结果语焉不详,公众强烈不满。

死者谭卓,1984年生,2006年毕业于浙江大学通信工程专业,家中独子,农村。
他的离去给家中父母带来沉重打击,痛不欲生。浙江大学校友对于校友的离去感受悲
殇,于肇事地点怀念。浙大院系领导闻讯赶往抚慰。

1、本次事故的视频:
1.1、杭州文二路飙车车祸 http://v.youku.com/v_show/id_XODk5ODU5ODg=.html
1.2、警方发布会 1 http://v.youku.com/v_show/id_XODk5NTA4NTI=.html
警方发布会 2 http://v.youku.com/v_show/id_XODk5NTEyMjg=.html
警方发布会 3 http://v.youku.com/v_show/id_XODk5NTE0MDA=.html

2、 国内各大媒体新闻报道
2.1 网易 富家子弟把城市道路当F1赛道终酿惨祸
http://news.163.com/09/0508/07/58PCAKQI00011229_2.html
2.2 中国新闻网 杭州一疑似改装车酿惨案 被撞男子当场死亡
http://www.chinanews.com.cn/sh/news/2009/05-07/1682001.shtml
2.3 新浪 年轻男子驾三菱跑车飙车撞死路人
http://news.sina.com.cn/s/p/2009-05-08/033417768110.shtml
2.4 新华社 马路当赛道 富家子文二西路飙车夺人命
http://www.zj.xinhuanet.com/website/2009-05/08/content_16468441_1.htm

3、胡某其母,车主,私企老板,陆XX,得知儿子及其同伙撞死人后现场言:
“夜里开开嘛,天还这么早,怎么好开的…… ”
不但没有对于儿子的责备,如此轻微劝诫而已。面对着脚下的尸体,如此惨无
人性的母亲……

4、肇事者新闻 F2卡丁车赛冠军

2009年4月24日星期五

什么叫倒霉

今天临走前十分钟,我手欠地运行了一个脚本,这个脚本调用了其他的脚本和一个刚刚改过的c++程序,产生了复杂的效应,简而言之,一个重要的数据文件夹被rm -rf了。

它大爷的!

找备份,发现这个分区是唯一一个不被自动备份进程覆盖的区。找恢复方法,发现我用的是加密的ext3,Google一通的结论是没办法。

还好实验还能用一系列脚本重复,是个时间问题,不过不爽度算是到了极点。

算是攒人品了。

2009年4月19日星期日

刚才简单算了一下,10万块钱能干什么

可以建造一个小型山寨集群机,22T的存储,88个核,每核主频3.0G,每核2G内存,最后还能剩下一两万的利润......
电脑真是便宜啊。

更新:Nvidia Tesla基于GPU的超级计算机,960个核,>3.7 Teraflops,只要9995刀,合7万多块.... 不过没有存储,只是计算能力。看来山寨货还是干不过正规军。

2009年4月16日星期四

Eclipse “*你妈的”?



Eclipse 3.4,代号Ganymede。我们都亲切地成为Eclipse gan4ni3ma1de,重音放在第一个字上,读起来非常有气势。

其实Ganymede是木星的卫星,发音是干你米德。这家伙也是太阳系最大的卫星,比我们的月球大一点不多。这里有一个干你米德的玉照,左起第四列上起第三位是干你米德同学。

2009年4月13日星期一

Vista vs. Leopard第一局,vista败(?)

我有个习惯,回到家把macbook接到外接LCD和键盘鼠标上当轻省台式机用。Leopard在笔记本屏幕关闭且有外接显示器的状态下,如果收到键盘或是鼠标的动作,便会唤醒到clamshell模式。Clamshell(贝壳)模式就是只用外接的显示器和键鼠,当作台式机一样使用。我的LCD有1920x1080的分辨率,Leopard在上面运作很正常,该有啥功能有啥效果都不打折扣。

今天偶然用Vista重复这件事情,首先vista就没能在笔记本屏幕盖住的情况下切换到外接显示器,还得把笔记本屏幕打开,重新设置它使用外接显示器。然后我发现,Vista在1920x1080分辨率下自动关闭了aero glass效果,变成了丑丑的vista basic界面。同样的一台机器,同样的硬件配置(废话),vista aero glass没能撑到1920x1080。

[谜之音:好像不公平诶,这是在Mac自家的硬件上,leopard当然胆子大些啦!!]

对了,我的macbook是较古早的一种,intel GMA950 64M共享显存..

2009年4月12日星期日

转载一个视频,Google的数据中心



Google最近公开了一个数据中心的一些视频和照片,只能用工程奇迹来形容。看看youtube的留言,观众们更是爽的不行。

vista sp1速度快了很多啊

最近给老师买了一部thinkpad X200,上面预装的是vista sp1。之前我用过vista,虽然有2G内存但是感觉还是慢,后来就放弃了。这次试用老师的笔记本,发现vista sp1速度很快啊,我在macbook上装了一个,果然好了很多,日常上网、写作等等工作很少有停顿感。前一段时间tuotuoxp就和我介绍过,说现在vista已经很好用了,果不余欺也。

2009年4月4日星期六

有道上升还是很强劲的,哈哈

今天在网上看到一个报道,说谷歌仍居中国搜索引擎的第二把交椅,并且给出了一个用户数量分布图。可以注意到的一个细节是有道已经超过了搜狗坐上了第三把交椅,这对于新生的有道来说是一个不错的成绩阿,祝贺祝贺!

不过这个报道的数据来源是一个之前没听说过的“生意宝网”,可靠性不是很高,权作八卦了。 :-)

2009年3月16日星期一

用Json来存储格式化数据

这篇文章本来是写给实验室同学们的,针对的是做文本处理实验中数据的存储问题。转帖在blog上留存,呵呵。

看看这个场景:你处理了一些文档,得到格式化的结果,包括正文、标题、时间、类别标签和作者。现在你想把这些结果写到文件里面,以便后面程序读取,或是仅仅作为归档。你会选择什么格式和方法来输出这个数据文件呢?下面有几个常见选择:

  • A: 写一个文本文件,第一行是标题,第二行是时间,第三行是类别标签,第四行是作者,最后一行是正文。读取的时候写一个(不算短的)程序解析这个文件。
  • B: 利用java的DataOutputStream,按顺序把正文、标题、时间、类别标签、正文和作者输出。读取的时候按照同样的顺序读出。
  • C: 创建一个类代表一个文档,如class Doc,其中的公共成员变量代表上述的内容,然后用Java的序列化机制写到文件中。读取的时候用反序列化读出。
  • D: 我很聪明,我发明了一种格式来存取。虽然复杂,但是(可)能节约空间。

这些方法都可行,但不一定是最好的方案,其中有一些常见的陷阱。

第一个陷阱是escaping。以A为例,如果正文中含有回车字符(这很常见),那么正文就可能占很多行,如何决定 正文什么时候结束呢?你可以事先去掉所有的回车字符,那日后如果想要按行分析该怎么办呢?如果你聪明地(谜之音:小聪明!)把回车都替换成一个其他字符 串,比如"_huiche_",那当原文中出现这个字符串时怎么办?别认为这不可能,在大规模数据处理中这几乎是一定的。如果你按照通行的办法,把所有的 回车都变成"\n",那么你就得处理"\"这个字符,复杂的规则会让你写很多的代码。A和D都可能被escaping问题困扰。

第二个陷阱是二进制兼容性。以B为例,看起来这个方法简洁漂亮,可如果另一个同学用C++,他想读你的数据,等待他 的就不是一个简洁漂亮的任务了。他需要仔细了解Java输出的格式,如何处理Java诡异的writeUTF输出。如果你恰好用的是方法C,那这位同学就 掉进了一个黑洞,反复研究Java的序列化协议,被折磨的苦不堪言。如果这位同学用的是不同字节序的电脑(如老Mac,或是Sun工作站)更是一场噩梦。 B、C和D方法都可能被二进制兼容性问题困扰。

第三个陷阱是可读性。假设你的数据用A方法保存,在磁盘上睡了一学期,然后另外一个同学(谜之音:或是你自己!)要 重新用这些数据,你还能记起每行代表什么么?更糟糕的是当时的程序可能已经不见了。A方法还好,能从数据的内容大致猜测一下,如果你用的是B、C、D方 法,该怎么去猜呢?如果你已经毕业了,其他同学猜起来的难度不亚于破解密码。A、B、C和D四种方法都受到可读性问题的困扰。

用JSON表示数据

这篇文章介绍了如何利用一种标准格式,JSON,来将格式化的数据存储到文件中,或是在程序之间传递。JSON可以由任何语言读取,可读性强,没有字节序问题,就是原作者人间蒸发,也可以从数据文件中了解到每个域都保存了什么内容。

还是继续前面的例子,在Java中,我们先定义一个类代表这种数据:

class Doc {
public String content;
public String title;
public String classLabel;
public long timestamp;
public String author;
}

对于一个Doc类的对象,我们可以用Google提供的Gson库把它变成一个标准的JSON字符串:

Doc d = someDocument;
Gson g = new Gson();
String jsonStr = g.toJson(d);

非常简单对吧,jsonStr的内容就像这样

{"content":"内容\n另外一行内容","title":"文档标题","classLabel":"体育","timestamp":99817827282,"author":"某人"}

我们通过肉眼观察就能发现这个字符串代表哪些信息,就是有一天完全没人知道数据是怎么生成的,还是能够解析。

用下面的方法可以把一个JSON字符串解析出来:

Doc d = gson.fromJson(jsonStr, Doc.class);

这样d的内容就是jsonStr中代表的内容了。

将JSON格式的数据保存到文件

如果要保存到文件,我建议将数据写到压缩的文本文件中,每行一个JSON字符串。假设所有的数据都放在List dataset中,数据类名是Data,那么把数据保存到文件的代码可以写为:

FileOutputStream fos = new FileOutputStream("data.gz");
GZIPOutputStream gos = new GZIPOutputStream(fos);
OutputStreamWriter osw = new OutputStreamWriter(gos, "UTF-8");
BufferedWriter output = new BufferedWriter(osw);

Gson gson = new Gson();
for (Data d : dataset) {
output.write(gson.toJson(d));
output.write('\n');
}
output.close();

读取数据到同样的一个List中,代码可以写为:

FileInputStream fis = new FileInputStream("data.gz");
GZIPInputStream gis = new GZIPInputStream(fis);
InputStreamReader isr = new InputStreamReader(gis);
BufferedReader input = new BufferedReader(isr);

Gson gson = new Gson();
List dataset = new LinkedList();
String line;
while ((line = input.readLine()) != null) {
dataset.add(gson.fromJson(line, Data.class));
}
input.close();

你可能注意到读写数据代码中壮观的一排new,是的,这很丑很麻烦。不过这么程式化的代码可以简单包一包,例如上面两段代码可以简化为

GzipTextFileWriter output = new GzipTextFileWriter("data.gz", "UTF-8");
Gson gson = new Gson();
for (Data d : dataset) {
output.writeLine(gson.toJson(d);
}
output.close();

GzipTextFileReader input = new GzipTextFileReader("data.gz", "UTF-8");
Gson gson = new Gson();
List dataset = new LinkedList();
String line;
while ((line = input.readLine()) != null) {
dataset.add(gson.fromJson(line, Data.class));
}
input.close();

只要写两个简单的wrapper class,GzipTextFileReader和GzipTextFileWriter就行了。

存储效率,空间和时间

聪明的你一定发现了,用Gson库把数据保存为JSON格式,其中多出了元信息,如"classLabel"。这些元信息在每条数据里面都有,这不是非常浪费么?另外,我们用字符串表示数字和布尔类型,这不也是浪费空间么?

如果我们不用GzipXXX,老老实实地写到文本文件里面,确实是浪费空间。但由于元信息高度重复,写入压缩文件后,JSON格式占用的空间并不比直接写二进制数据多出多少。下面我们用一个小实验来证明。

我们写10000条数据,每条数据由一个字符串,一个整数,一个浮点数和一个布尔值组成,具体的取值随机,字符串长度相似,约十多个字符。我们用三种方法来保存数据,第一种是直接用二进制的DataOutputStream来保存每条数据,没有任何冗余;第二种是利用Json格式,但不保存如"classLabel"之类的元信息;第三种是用上面介绍的Gson库,同时保存元信息和数据。三种方法我们都输出压缩和不压缩两种数据文件。最终文件的尺寸在下表中列出。


不压缩压缩
二进制396KB260KB
Json无元信息648KB264KB
Gson1024KB280KB

由表中数据可以看出,1)Gson输出虽然比前两种方法尺寸大,但是在压缩后,多出的部分非常有限 2)数据压缩和不压缩有很大差别,压缩的Gson仍比不压缩的二进制数据小很多。

听起来可能有点反常,但是输出到压缩文件比直接输出到文本文件要快,而不是慢。这是因为现代CPU的速度远快于磁 盘,写文件的时候主要的时间花在磁盘的机械动作上。如果事先对数据进行压缩,会减少实际写入的字节数,从而节约写数据的时间。而压缩数据对于现代CPU来 说易如反掌,多数情况下消耗的资源都很少。

和Hadoop联用

在Hadoop的map-reduce中,除了极端要求性能或明显可以节约时间的简单情况,我们都推荐用Gson+JSON来表示数据。 Hadoop的key和value如果是Text格式,都会自动进行压缩,所以大家也无需担心压缩问题。Gson本身的序列化和反序列化代码经过仔细优 化,性能很好。

结论

(谜之音:怎么结论都出来了,这是论文么???!!)

使用JSON格式和Gson库来表示数据并存储在压缩文件,这种方法更方便,更快,更节约空间。如果有朝一日忘记了数据保存的格式,看看文件内容就知道了,避免冏况发生。

参考资源

JSON格式标准说明: http://www.json.org

Gson库: http://code.google.com/p/google-gson/

后记:Google的protocol buffer格式也是一个不错的选择,不过它需要先用一种特定的语言描述数据格式,然后从格式文件创建出具体的类代码,数据的序列化和反序列化都是用生成的代码实现的。如果原数据格式描述和代码丢了,基本上也就废了。

2009年3月15日星期日

2009年3月14日星期六

Google Docs最近很不稳定啊

前几天Google Docs打不开,我以为是临时现象,结果今天spreadsheets又打不开了。不知道Google Docs那帮人在想些啥,再这样搞下去,就该流失用户了...

2009年2月19日星期四

2009年2月10日星期二

闲扯公司中VPN的安全

VPN,包括IPSec啊或是加密的PPTP啊什么的,本身是很安全的,一般都是用128位的算法来对来往数据加密。解开VPN的加密算法需要数千台计算机工作数千年。所以,迄今为止还没有听说通过破解加密算法来攻破VPN的真实案例,这也许是因为我孤陋寡闻,但是至少很稀有。

不 过,就像木桶能装多少水依靠最短的一块木板,VPN安全也有一块短板,那就是我们自己和自己的家用电脑。要想通过VPN来窃取公司机密,最方便也是最 常用的方法不是破解复杂的数学密码,而是想办法从相关人员手里偷到钥匙(偷窥到密码)。甚至在多数情况下,密码都不是“偷”去的,而是大摇大摆抄走 的,或是员工主动提供的。这听起来可笑,但是却常常发生在缺乏安全知识和意识的员工身上。下面通过几个例子来说明:

例子一:公司员工美女小A,在家里想远程连回公司办公,但是VPN总也不工作。小A想到正追求自己的宅男小C是电脑高手,于是搬来小C替自己解决。为了节约时间减少 麻烦,小A就把自己的密码“prada”告诉了小C。小C很快的解决了问题,带着小A的感谢和微笑(谜之音:还有密码!!!)回家了。小A找到帅气新男友 小D半月后,发生了公司客户数据以每条1块钱的价格泄露给竞争对手的消息,小A傻眼了(谜之音:她可能连眼都没傻)。

教训一:无论如何,不要把自己的密码泄露给其他人,包括公司的同事。公司的同事可能会利用你的身份进行信息犯罪,并栽赃给你。如果实在需要找小C帮忙,也记得自己输入密码,不要让小C看到。

例子二:公司员工美女小A,在家里想远程连回公司办公,输入了自己的用户名Amy和密码prada,顺利连入公司网络。情场失意的网络高手小C,在深夜报复社会,用程序猜测小A在公司VPN的密码。小C不是胡猜,他用一个含有很多常用密码、英文单词、从1970年到现在每天日期的文件作为猜测的备选,不出几分 钟,电脑上提示prada这个常见单词被猜中了。几天后,发生了公司客户数据以每条1块钱的价格泄露给竞争对手的消息。

教训二:不要使用简单的密码,例如自己的生日、英文单词、较短的随机字符串(例如小于5位字母,黑客完全可以把5个英文字母的所有组合尝试一遍)。密码要长,最好大于10位,要没有规律,要包含字母、数字和标点符号,例如“sak@32o8.fjs”就是一个不错的密码,黑客老死也无法猜中。记不住这么变 态的密码怎么办?多记就好了,一般来说几天之后就会背下来。我还有个小技巧,是利用符合发音规则的假词造长密码,例如coporine92simory!,这个密码比上面的好记,也相当安全。

例子三:公司员工美女小A,在家里想远程连回公司办公,输入了自己的用户名Amy和无敌密码i~dont~th1nk~u~can~guess~this~password293,顺利连入公司网络。情场失意的网络高手 小C在深夜报复社会,通过QQ、MSN等大量发送木马病毒。小A的机器没有开防火墙(嫌麻烦)和杀毒软件(嫌慢且不想花钱),已经不幸中招几天还没有察觉。小C发 现某台电脑受到自己控制,这台电脑又有一个活动的VPN链接,于是偷偷远程潜入小A的电脑,又通过小A电脑上已经连接的VPN进入公司。几天后,发生了公司客户数据以每条1块钱的价格泄露给竞争对手的消息,小A自己的私房照片也被贴在了火爆的成人网站上。

教训三:一定要开启防火墙,一定要及时更新系统,一定要安装杀毒软件并及时更新。黑客从来不是针对你行动的,他们广撒大网,只有安全性弱的电脑才会中招。 一般公司会配备集中采购的杀毒软件,如果没有的话,可以考虑Windows防火墙,AVG免费杀毒软件,360安全卫士和墨者安全专家等软件,这些都是完全免费的,能给电脑带来不错的基本保护(但是如果涉及高度敏感数据一定要咨询相关专业人员,如公司信息安全专员)。

我选择美女小A作为主角也是有意义的。公司里面不乏计算机达人,他们自己的电脑防护的如铁桶一般百毒不侵,但是像小A这样对技术不感冒的员工就是企业安全的短板。要修补这块短板,一般就需要专职IT人员的检查和不厌其烦的培训了,呵呵。

2009年1月27日星期二

在Java中检测cpu数目

如果我们想在Java中利用多核处理器,那么就要按照实际的处理器数目来创建线程。如何得到处理器数目呢?一句话: Runtime.getRuntime().availableProcessors(); 这是一个int值,在我的macbook上返回的就是2,呵呵,简单方便。

2009年1月20日星期二

Is Java ready for multi-cores?

The title is a little big. -_-

Nowadays most computers have two independent CPU cores, for example, my MacBook has two in the Intel Core 2 Duo. Question is: Can we get any benefits from the additional core when coding with Java? Assuming we programmers take care of threading and algorithm parallelization.

The key to this question is whether we can run two Java threads simultaneously on different cores. In C/C++, we can use SetThreadAffinityMask() for Windows and thread_processor_bind_np() in POSIX systems like Linux. Is there similar mechanism in Java threading? A Google search brings up some relevant pages, like this article by Patrick on JavaWorld. Patrick argued that Java 1.1.3 VM cannot utilize more than 2 CPUs well (Oops, I have only 2..).

To get my hands dirty, I wrote a small program in Java to see if it can use all my cores.


public class MultiCoreWorker extends Thread {

@Override
public void run() {
int a = 0;
while (true) {
a = (a + 1) % 1000;
}
}

public static void main(String[] args)
throws InterruptedException {
MultiCoreWorker t1 = new MultiCoreWorker();
MultiCoreWorker t2 = new MultiCoreWorker();

t1.start();
t2.start();
Thread.sleep(1000000000);
}

}


The code basically do nothing but adding a number, which will take all available CPU cycles. When 2 MultiCoreWorker are running, the system have a 100% CPU usage on both cores. I ran the code multiple times to assure that it's stable. A screenshot of the Activity Monitor is as follows.


It seems at least Java threads can expand on 2 cores well ( On Mac OS X leopard with client JVM 6.0). I'll try to make some of my code parallel and see how much time can it saves by utilizing 2 cores.

The funny thing happened when running just a single thread. I commented out the codes with t2, and re-ran the program. Only one core was used, that's not beyond our expection. Interesting thing is in the following screenshot, the thread was actually jumping between the cores.

See the complementary curves just under the label "CPU Usage" ? :) Our code do not have any I/O operation, so there would be no I/O waiting. It clearly indicates that JVM can move threads between CPUs at any time. Cool...