转:非主流并发工具之 ForkJoinPool

ForkJoinPool 是 Java SE 7 新功能“分叉/结合框架”的核心类,现在可能乏人问津,但我觉得它迟早会成为主流。分叉/结合框架是一个比较特殊的线程池框架,专用于需要将一个任务不断分解成子任务(分叉),再不断进行汇总得到最终结果(结合)的计算过程。比起传统的线程池类 ThreadPoolExecutorForkJoinPool 实现了工作窃取算法,使得空闲线程能够主动分担从别的线程分解出来的子任务,从而让所有的线程都尽可能处于饱满的工作状态,提高执行效率。

ForkJoinPool 提供了三类方法来调度子任务:

execute 系列
异步执行指定的任务。
invokeinvokeAll
执行指定的任务,等待完成,返回结果。
submit 系列
异步执行指定的任务并立即返回一个 Future 对象。

子任务由 ForkJoinTask 的实例来代表。它是一个抽象类,JDK 为我们提供了两个实现:RecursiveTaskRecursiveAction,分别用于需要和不需要返回计算结果的子任务。ForkJoinTask 提供了三个静态的 invokeAll 方法来调度子任务,注意只能在 ForkJoinPool 执行计算的过程中调用它们。

ForkJoinPoolForkJoinTask 还提供了很多让人眼花缭乱的公共方法,其实它们大多数都是其内部实现去调用的,对于应用开发人员来说意义不大。

下面以统计 D 盘某文件夹文件个数为例。这实际上是对一个文件树的遍历,我们需要递归地统计每个目录下的文件数量,最后汇总,非常适合用分叉/结合框架来处理:

   让人围观的是,这并不比单线程的Files.walkFileTree(...)
refer:http://www.blogjava.net/shinzey/archive/2012/02/09/368312.html

流程图绘制软件介绍

    因为工作中经常需要用到流程图软件,上网仔细挑选了几款相对比较优秀的软件,一一介绍。
注意:流程图也叫Flowchart,不是思维导图Mind Map。不过有的软件既能绘制Mind Map,也能绘制Flowchart,如Edraw Mind Map(也称亿图图示专家),不过亿图如今有了专门的Flowchart了。

1.Diagram Designer


免费软件,windows平台,最新版本 1.25.下载地址:http://meesoft.logicnet.dk/
Diagram designer
安装包体积:1.3M
可以画一些简单的流程图,GUI示意图(Diagram Designer的特色就在这里),主要的图元有:简单图形,流程图,GUI窗口和元素,UML类图。
优点和特色:体积小,可画GUI示意图,展示窗口,表格等。
缺点:图元样式不够丰富,太少了。属性和文本编译不够直观,另外导出的图像质量不是很好,特别是曲线图形锯齿比较明显。导出时,不会智能的选择指导出可见部分。因此使用前需要预先设置好画布大小。
输出效果:diagram Designer.png

2.Dia


免费软件,跨平台,最新版本0.97.2,下载地址:http://projects.gnome.org/dia/
WINDOWS安装包 19M.由于dia最初是linux平台下的软件,所以发扬了linux桌面软件bug比较多,用户不友好,难适应的传统。

阅读剩余部分...

SPDY 协议介绍

目前支持SPDY协议的应用有:firefox开发板,jetty8等。
SPDY 目前是一种应用层实验性协议,旨在让互联网访问更快速,减少web页面的延迟。

SPDY 设计特点

协议在SSL层的基础上,增加了一个session 层,从而在一个tcp 连接基础上,实现了多并发和交叉流传输

HTTP 的GET ,POST 仍旧采用旧有的消息格式,当然SPDY 协议对原有的数据做了封装和编码,这里采用Wrapper设计模式。
spdy.png

流是双向的,比如,既可以从客户端发起,也可以从服务器端发起(PUSH)

SDPY的目标就是通过其基本特性和高级特性,来达到低访问延迟

基本特性包括

1  流复用

SPDY最牛逼的地方,是允许在一个TCP连接里面,允许无限并发流(在双方资源可承受的情况下)。因为请求是在一个单一的通道交错传输,TCP的可以达到很高的效率,从而更少的网络连接需要,可以以很高的 数据密度做传输。
2  具备优先级的请求
虽然无限的并行数据流的解决了序列化的问题,但是它们引入了另一个问题:如果由于信道带宽的限制,客户端可能会阻止怕堵塞通道的要求。为了克服这个问题,SPDY实现请求的优先次序:客户端可以请求尽可能多的项目,每个请求分配一个优先级。这样即使高优先级的请求仍处在pending状态,通道也不会传输非关键的,低优先级的请求,这样就有效地阻止了传输拥塞。
3  HTTP Header 压缩
对于HTTP 请求,响应头,SPDY都做了压缩,这样包更小,对于RESTFUL类型的WEB2.0 ,or OpenAPI 业务,将会有可观的效率提升。
高级特性

1  服务器端推送
SPDY通过X-Associated-Content 协议头来向客户端推送数据,头通知客户端,我要向你推送资源,准备接收好了。最近火爆的Google+ ,如果你用chrome浏览器,默认就采用SPDY技术,并且开启了服务器推送技术。服务器的推技术,全面提升了用户体验,是G+ 产品很快占据了足够多的优势,最近Facebook 开发自己的浏览器,也有摆脱现在技术限制的考虑
2  服务器暗示
不像上面提到的PUSH 技术,服务器会先告诉浏览器,你可以下载ABC资源了,这个ABC资源,可能就是下一个页面的JS ,CSS ,或者内容。服务器不会主动推送的,仍旧等待客户端请求,这对于低速网络,是个很大的优化,有点类似于我们的预加载技术
效果测试
TOP25 网站的平均页面加载时间

DSL 2 Mbps downlink, 375 kbps uplink Cable 4 Mbps downlink, 1 Mbps uplink

Average ms Speedup Average ms Speedup
HTTP 3111.916
2348.188
SPDY basic multi-domain* connection / TCP 2242.756 27.93% 1325.46 43.55%
SPDY basic single-domain* connection / TCP 1695.72 45.51% 933.836 60.23%
SPDY single-domain + server push / TCP 1671.28 46.29% 950.764 59.51%
SPDY single-domain + server hint / TCP 1608.928 48.30% 856.356 63.53%
SPDY basic single-domain / SSL 1899.744 38.95% 1099.444 53.18
SPDY single-domain + client prefetch / SSL 1781.864 42.74% 1047.308 55.40%

转:JVM伪共享

   伪共享False sharing说明JVM底层技术也不让人那么放心。

内存缓存系统中基本单元是高速缓存行(Cache lines). cpu会把数据从内存加载到高速缓存中 ,这样可以获得更好的性能,高速缓存默认大小是64 Byte为一个区域,一个区域在一个时间点只允许一个核心操作,也就是说不能有多个核心同时操作一个缓存区域。

因为高速缓存是64字节,而Hotspot JVM的对象头是两个部分组成,第一部分是由24字节的hash code和8字节的锁等状态标识组成,第二部分是指向该对象类的引用。基本类型字节如下:
doubles (8) and longs (8)
ints (4) and floats (4)
shorts (2) and chars (2)
booleans (1) and bytes (1)
references (4/8)

因此,一个高速缓存64字节可以放下多个字段,如果这多个字段位于同一个高速缓存区,虽然它们是类的不同字段,如下代码:
Class A{
   int x;
   int y;
}
x和y被放在同一个高速缓存区,如果一个线程修改x;那么另外一个线程修改y,必须等待x修改完成后才能实施。
虽然两个线程修改各种独立变量,但是因为这些独立变量被放在同一个高速缓存区,性能就影响了。测试结果如后面。
当多核CPU线程同时修改在同一个高速缓存行各自独立的变量时,会不自不觉地影响性能,这就发生了伪共享False sharing,伪共享是性能的无声杀手。

解决方便是将高速缓存剩余的字节填充填满(pad),确保不发生多个字段被挤入一个高速缓存区,下面测试结果图就是和填充后性能比较。

实现字节填充的框架有 Disruptor,在RingBuffer中实现填充。关于Disruptor可见infoQ这个视频,用1毫秒的延时得到100K+ TPS吞吐量,JDK的ArrayQueue并行环境不见得是最快的,该视频后面讨论很多,让人大跌眼镜啊,开放源码多有好处啊,别人能发现你不能发现的漏洞。另外一篇解剖Disruptor

C#也有类似伪共享发生,见这里
jvm_False_sharing.png
参考:http://www.jdon.com/jivejdon/thread/42451
LMAX架构
disruptor - 并发编程框架
http://www.infoq.com/presentations/LMAX

mysql的BASE64编码和解码实现

刚好需要,找到了这个东西。mysql有MD5,AES,DES等加密函数,不过恰恰却没有BASE64编码解码函数。找到了原文:http://forums.mysql.com/read.php?10,404800,404800#msg-404800
http://wi-fizzle.com/downloads/base64.sql
下面的代码来自Gist https://gist.github.com/1724446

当然了,除非特殊需要,不推荐这么使用。如果技术够的话,可以写成UDF。
汉字等还需要注意编码

php的exec函数在linux下返回值不能为负数的问题

l来自雪候鸟的文章:http://www.laruence.com/2012/02/01/2503.html,正好解释了这个问题。
原问题来自这里
http://bbs.phpchina.com/thread-230760-1-1.html
string exec ( string $command [, array &$output [, int &$return_var ]] )

第三个参数, 怎么不能接收负数??
这里的&$return_var就是程序返回值,起初我的回答是可以为负数。
一般在C语言里我们会这样写
#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("^_^\n");
    return -5;
}
这个-5就是返回值,但习惯上是写成0或者1的。
注意:很多人的C代码里把main函数写成 void main() 这样实际上是不对的,详细的就不说了。
把上面的代码编译后,到CMD下运行,然后就能看到输出结果了。接着,输入“echo %ERRORLEVEL%”,回车,就可以看到程序的返回值了。这个%ERRORLEVEL%就代表了程序的返回状态。在WIN下确实是可以为负数的。如图所示:
exec_return_win.png
,php调用也是正常的。
E:\dev\php535>php -r "exec('return.exe',$out,$a);var_dump($a);"
int(-2)
但是到了linux下,始终为正数,刚开始怀疑是权限问题,用了chmod +x后,排除了权限问题。
exec("/home/wwwroot/test/rtest.out 2>&1",$out,$a);
var_dump($out,$a);
array(1) { [0]=> string(3) "^_^" } int(251)
看起来成了256+return val,可以看到实际上返回了负数,只不过被转换成正数了。
接着看了下standard/exec.c里的源代码,没发现啥端倪,干到很奇怪,突然想到自己忘了一步。忘了看程序返回给OS的值了.
可以使用echo $? 显示最后命令的推出状况。
-bash-3.00$ vi main.c
-bash-3.00$ gcc -o ./mm main.c
-bash-3.00$ ll
total 48
drwxr-xr-x  3 www www 4096 May  4  2011 2011
drwxr-xr-x  6 www www 4096 Jun 23  2011 eoc
-rwxr-xr-x  1 www www 7131 Feb  1 12:47 hello
-rw-r--r--  1 www www    3 Feb  1 12:51 hello.c
-rw-r--r--  1 www www   99 Feb  1 12:50 main.c
-rwxr-xr-x  1 www www 4714 Feb  1 12:51 mm
drwxr-xr-x  3 www www 4096 Jun 24  2011 test
-bash-3.00$ ./mm
^_^
-bash-3.00$ echo $?
251
-bash-3.00$
这样就可以看看exec返换给OS的值是多少。
在linux下,这个返回值就是无符号类型,返回的是一个正数,所以传给php也是正数了,php实际上也是调用的exec所返回的值。

     OUT了,也许linux就是这么规定的,程序中泰返回值为1~255区间,而自己不清楚这个规则。不过还没有确定是否linux里就是这么规定的。虽然问题很蛋疼,意义不大,不过也可以在这里留给遇到类似问题的人参考。不过到这里也没深究的必要了。谁要是真想彻底搞清楚,可以看看shell这块
    Page :
  1. 1