MySQL默认排序

MySQL默认排序 SELECT * FROM tbl – this will do a “table scan”. If the table has never had any DELETEs/REPLACEs/UPDATEs, the records will happen to be in the insertion order, hence what you observed. 大致意思为,一个myisam引擎表在没有任何的删除,修改操作下,执行 select 不带order by,那么会按照插入顺序进行排序。 If you had done the same statement with an InnoDB table, they would have been delivered in PRIMARY KEY order, not INSERT order. Again, this is an artifact of the underlying implementation, not something to depend on. 对于innodb引擎表来说,在相同的情况下,select 不带order by,会根据主键来排序,从小到大

2016-01-12 · 1 min · 78 words · -

WNDR4300 openwrt

‘WNDR4300 openwrt’ https://wiki.openwrt.org/zh-cn/toh/netgear/wndr4300 WNDR4300 Flash容量: 128 MiB NAND RAM: 128 MiB mips, not mipsle go build … GOMIPS=softfloat WNDR4300有两种固件,一种为 …ubi-factory.img 格式,一种为 …squashfs-sysupgrade.tar 格式。 其中 img 格式只能用 tftp 的方法刷入。而 tar 只能通过已刷了Openwrt的WEB端进行刷入。 https://downloads.openwrt.org/releases/19.07.3/targets/ar71xx/nand/openwrt-19.07.3-ar71xx-nand-wndr4300-ubi-factory.img https://downloads.openwrt.org/releases/17.01.4/targets/ar71xx/nand/lede-17.01.4-ar71xx-nand-wndr4300-squashfs-sysupgrade.tar opkg update opkg install libopenssl opkg list_installed 下载img文件 http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/nand/openwrt-15.05-ar71xx-nand-wndr4300-ubi-factory.img 进路由器界面,找到『固件升级』,然后上传这个包点确定。路由器就会自动刷成 openwrt 固件,等待它重启后再连路由器就大功告成了。 下载升级包: http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/nand/openwrt-15.05-ar71xx-nand-wndr4300-squashfs-sysupgrade.tar稍后在 openwrt 系统里给升级。 基础设置 新的 openwrt 固件默认是不开 wifi 的,所以第一次你得用网线连上路由器,进去后应试能看到 luci 界面,这里会让你输入密码,用户名默认是 root,此时密码还是个空的,随便输一个回车进回界面, 先设置一密码吧,直接点 luci 界面上面的警告条后进入密码设置界面,输入一个你自己的密码,顺便把下面的 远程ssh给勾上。 让你的路由器连上网,按顶部菜单栏进入net-interface选择你的接口,通常是 WAN 口,点旁边的 eidt,然后选择 ppope,点切换,然后输入你的宽带帐号和密码,然后应用。 此时你的路由已经能上网了。 https://wiki.openwrt.org/zh-cn/toh/netgear/wndr4300 http://dlmao.com/wndr4300-%E6%8A%98%E8%85%BE-openwrt-%E8%AE%B0.html http://dlmao.com/wndr4300-zhe-teng-openwrt-ji-zhong-ji-xiu-zheng-ban.html https://bigeagle.me/2016/02/ipset-policy-routing/ https://php-rmcr7.rhcloud.com/openwrt-fq/ https://php-rmcr7.rhcloud.com/openwrt-fq/embed/#?secret=xcThHfkyLS https://cokebar.info/archives/948 https://cokebar.info/archives/948/embed#?secret=k8dinHiD9m https://forum.archive.openwrt.org/viewtopic.php?id=16599

2016-01-09 · 1 min · 76 words · -

Netty 中 IOException,Connection reset by peer 与 java.nio.channels.ClosedChannelException,null

‘Netty 中 IOException,Connection reset by peer 与 java.nio.channels.ClosedChannelException,null’ http://www.cnblogs.com/zemliu/p/3864131.html 最近发现系统中出现了很多 IOException: Connection reset by peer 与 ClosedChannelException: null 深入看了看代码, 做了些测试, 发现 Connection reset 会在客户端不知道 channel 被关闭的情况下, 触发了 eventloop 的 unsafe.read() 操作抛出 而 ClosedChannelException 一般是由 Netty 主动抛出的, 在 AbstractChannel 以及 SSLHandler 里都可以看到 ClosedChannel 相关的代码 AbstractChannel static final ClosedChannelException CLOSED_CHANNEL_EXCEPTION = new ClosedChannelException(); static { CLOSED_CHANNEL_EXCEPTION.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); NOT_YET_CONNECTED_EXCEPTION.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); } @Override public void write(Object msg, ChannelPromise promise) { ChannelOutboundBuffer outboundBuffer = this.outboundBuffer; if (outboundBuffer == null) { // If the outboundBuffer is null we know the channel was closed and so // need to fail the future right away. If it is not null the handling of the rest // will be done in flush0() // See https://github.com/netty/netty/issues/2362 safeSetFailure(promise, CLOSED_CHANNEL_EXCEPTION); // release message now to prevent resource-leak ReferenceCountUtil.release(msg); return; } outboundBuffer.addMessage(msg, promise); } ...

2016-01-07 · 5 min · 878 words · -

RTEMS

RTEMS 为什么需要操作系统? 1.计算机是由CPU、内存、磁盘、显卡、声卡等许许多多设备组成的,而且这些设备的厂商众多,品种繁多,而且不同厂商生产的同种设备虽然完成同种功能,但是具体细节却存在千差万别; 2.为了正确地管理和使用这些设备来实现具体的应用,这样程序员就得了解和掌握各种设备的工作原理。而且对于同种设备,由于不同的硬件厂商在实现细节上的差异使得程序员再次陷入了复杂的硬件控制的深渊。 3.在硬件的基础上加载一层软件来管理整个系统; 4.操作系统通过设备驱动程序来与计算机硬件打交道,通过一系列的功能模块将整个计算机硬件系统抽象成为一个公共、统一、开放的接口,从而使得程序员不必再陷入各种硬件系统的具体细节。 什么是操作系统? 1.操作系统(Operating System,简称OS)是管理计算机系统的全部硬件资源包括软件资源及数据资源; 2.控制程序运行; 3.改善人机界面; 4.为其它应用软件提供支持等,使计算机系统所有资源最大限度地发挥作用; 5.为用户提供方便的、有效的、友善的服务界面。 什么是实时操作系统(RTOS)? 实时操作系统(RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的操作系统。 什么是实时? 响应时间快: 事件发生后,能以最快的速度对事件进行响应; 响应时间是确定的: 事件处理的延迟时间、处理持续时间、处理截止时间都有上限与下限,所有动作必须在这个时间范围内发生。 RTOS分类? 实时操作系统有硬实时和软实时之分: 硬实时要求在规定的时间内必须完成操作,否则会引起非常严重的错误,这是在操作系统设计时保证的; 软实时则只要按照任务的优先级,尽可能快地完成操作即可。 什么是TRON? TRON 全称是 (The Real-time Operating system Nucleus); ITRON(Industrial TRON)是一个由多家著名IT企业牵头的协议制定组织,同时IRTON也代表实时嵌入式系统的一个标准; ITRON提出了实时操作系统的一系列规范(包括系统调用接口规范,任务调度接口规范,TCP/IP网路链接API规范,本地与远程调试接口规范等等),遵循这个规范的操作系统上层软件可以相互移植。

2016-01-06 · 1 min · 35 words · -

maven profile

maven profile http://haohaoxuexi.iteye.com/blog/1900568 4 profile介绍 4.1 profile简介 profile可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。比如说,我们可以通过profile定义在jdk1.5以上使用一套配置信息,在jdk1.5以下使用另外一套配置信息;或者有时候我们可以通过操作系统的不同来使用不同的配置信息,比如windows下是一套信息,linux下又是另外一套信息,等等。具体的激活条件有哪些我在后文会讲到。 4.2 profile的定义位置 对于使用Maven3,我们可以有多个地方定义profile。定义的地方不同,它的作用范围也不同。 (1) 针对于特定项目的profile配置我们可以定义在该项目的pom.xml中。 (2) 针对于特定用户的profile配置,我们可以在用户的settings.xml文件中定义profile。该文件在用户家目录下的".m2"目录下。 (3) 全局的profile配置。全局的profile是定义在Maven安装目录下的"conf/settings.xml"文件中的。 4.3 profile中能定义的信息 profile中能够定义的配置信息跟profile所处的位置是相关的。以下就分两种情况来讨论,一种是定义在settings.xml中,另一种是定义在pom.xml中。 4.3.1 profile定义在settings.xml中 当profile定义在settings.xml中时意味着该profile是全局的,它会对所有项目或者某一用户的所有项目都产生作用。因为它是全局的,所以在settings.xml中只能定义一些相对而言范围宽泛一点的配置信息,比如远程仓库等。而一些比较细致一点的需要根据项目的不同来定义的就需要定义在项目的pom.xml中。具体而言,能够定义在settings.xml中的信息有 、和。定义在里面的键值对可以在pom.xml中使用。 4.3.2 profile定义在pom.xml中 定义在pom.xml中的profile可以定义更多的信息。主要有以下这些: l l l l l ...

2016-01-06 · 1 min · 145 words · -

python property

python @property 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑。为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数: class Student(object): def get_score(self): return self._score def set_score(self, value): if not isinstance(value, int): raise ValueError('score must be an integer!') if value < 0 or value > 100: raise ValueError('score must between 0 ~ 100!') self._score = value 现在,对任意的Student实例进行操作,就不能随心所欲地设置score了: s = Student() s.set_score(60) # ok! s.get_score() 60 s.set_score(9999) Traceback (most recent call last): … ValueError: score must between 0 ~ 100! 但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。 ...

2016-01-06 · 1 min · 206 words · -

nftables iptables

nftables iptables 跟iptables相比,nftables带来了一系列的好处 更易用易理解的语法 表和链是完全可配置的 匹配和目标之间不再有区别 在一个规则中可以定义多个动作 每个链和规则都没有内建的计数器 更好的动态规则集更新支持 简化IPv4/IPv6双栈管理 支持set/map等 支持级连 (需要内核4.1+) 新的防火墙子系统/包过滤引擎Nftables将在Linux3.13中替代有十多年历史的iptables。iptables/netfilter在2001年加入到2.4内核中。诞生于2008年的NFTables设计替代iptables,它提供了一个更简单的kernelABI,减少重复代码,改进错误报告,更有效的支持过滤规则。 除了iptables,NFTables还将替代ip6tables、arptables和ebtables。Linux内核的第一代包过滤机制是ipfwadm (1.2.1内核,1995年) ,之后是ipchains (1999年) ,iptables、Nftables是第四代。 http://luxiaok.blog.51cto.com/2177896/1312846 http://segmentfault.com/a/1190000000410970 Linux 3.13 带来了很多特性。nftables也是第一次正式发布。nftables是一个致力于替换现有的{ip,ip6,arp,eb}tables框架 (也就是大家熟知的iptables) 的项目。然而,Linux3.13中的nftables版本还是不完整的,还缺少一些重要的特性。这些特性会在后续的Linux版本中发布。大多数场景下nftables已经可以使用,但是完整的支持 (即,nftables优先级高于iptables) 应该在Linux 3.15。 nftables引入了一个新的命令行工具nft。nft是iptables及其衍生指令 (ip6tables,arptables) 的超集。同时,nft拥有完全不同的语法。是的,如果你习惯于iptables,这是个不好的消息。但是有一个兼容层允许你使用iptables,而过滤是由内核中的nftables完成的。 到目前为止,只有非常少的文档资料。你可以找到我的nftables快速开始,其他的一些初步文档很快就会公开。

2016-01-05 · 1 min · 33 words · -

SSDP

SSDP 简单服务发现协议 (SSDP,Simple Service Discovery Protocol) 是一种应用层协议,是构成通用即插即用(UPnP)技术的核心协议之一。简单服务发现协议提供了在局部网络里面发现设备的机制。控制点 (也就是接受服务的客户端) 可以通过使用简单服务发现协议,根据自己的需要查询在自己所在的局部网络里面提供特定服务的设备。设备 (也就是提供服务的服务器端) 也可以通过使用简单服务发现协议,向自己所在的局部网络里面的控制点声明它的存在。[1] 简单服务发现协议是在HTTPU和HTTPMU的基础上实现的协议。[1] 按照协议的规定,当一个控制点 (客户端) 接入网络的时候,它可以向一个特定的多播地址的SSDP端口使用M-SEARCH方法发送"ssdp:discover"消息。当设备监听到这个保留的多播地址上由控制点发送的消息的时候,设备会分析控制点请求的服务,如果自身提供了控制点请求的服务,设备将通过单播的方式直接响应控制点的请求。[2] 类似的,当一个设备接入网络的时候,它应当向一个特定的多播地址的SSDP端口使用NOTIFY方法发送"ssdp:alive"消息。控制点根据自己的策略,处理监听到的消息。考虑到设备可能在没有通知的情况下停止服务或者从网络上卸载,“ssdp:alive"消息必须在HTTP协议头CACHE-CONTROL里面指定超时值,设备必须在约定的超时值到达以前重发"ssdp:alive"消息。如果控制点在指定的超时值内没有再次收到设备发送的"ssdp:alive"消息,控制点将认为设备已经失效。[2] 当一个设备计划从网络上卸载的时候,它也应当向一个特定的多播地址的SSDP端口使用NOTIFY方法发送"ssdp:byebye"消息。但是,即使没有发送"ssdp:byebye"消息,控制点也会根据"ssdp:alive"消息指定的超时值,将超时并且没有再次收到的"ssdp:alive"消息对应的设备认为是失效的设备。[2] 在IPv4环境,当需要使用多播方式传送相关消息的时候,SSDP一般使用多播地址239.255.255.250和UDP端口号1900。 根据互联网地址指派机构的指派,SSDP在IPv6环境下使用多播地址FF0x::C,这里的X根据scope的不同可以有不同的取值。[3]

2016-01-05 · 1 min · 19 words · -

appassembler-maven-plugin

appassembler-maven-plugin Goals Overview appassembler:assemble Assembles the artifacts and generates bin scripts for the configured applications. appassembler:create-repository Creates an appassembler repository. appassembler:generate-daemons Generates JSW based daemon wrappers. maven 自动生成运行脚本插件appassembler-maven-plugin 博客分类: maven appassembler-maven-plugin可以自动生成跨平台的启动脚本,省去了手工写脚本的麻烦,而且还可以生成jsw的后台运行程序。 appassembler的配置比较简单,在pom.xml的配置文件加入插件配置。 比如说不同的启动脚本,可以如下配置 Xml代码 org.codehaus.mojo appassembler-maven-plugin 1.2.1 conf ...

2016-01-05 · 1 min · 110 words · -

Java Service Wrapper

Java Service Wrapper http://www.cnblogs.com/fsjohnhuang/p/4019267.html Java魔法堂: 以Windows服务的形式运行Java程序 一、前言 由于防止维护人员误操作关闭Java控制台程序,因此决定将其改造为以Windows服务的形式运行。弄了一个上午总算搞定了,下面记录下来,以供日后查阅。 二、Java Service Wrapper 官网地址: http://wrapper.tanukisoftware.com/doc/english/download.jsp JavaServiceWrapper以守护进程或windows服务的方式运行java程序。JSW提供四种方案改造原有项目,以实现守护进程或windows服务的方式运行。而且还提供JVM监控功能和自动重启功能,反正十分强大的样子。 方式1: WrapperSimpleApp 用于通过同一个类实现启动和关闭的程序。 官方推荐使用该方式加工原有项目,好处是简单,且不用修改原有项目的代码。 步骤1: 下载并解压得到工具包,目录结构如下 / |- bin,wrapper控制windows服务的bat文件 |- conf,wrapper配置文件 |- doc,教程 |- lib,wrapper的依赖包 |- logs,日志 |- src,模板 |- conf |- bin 步骤2: 搭建项目结构: 新建项目发布目录 (假设为agent) ,然后将src下的conf和bin复制到agent下,并且将conf和bin下的文件重命名,去掉`.in`后缀。然后将bin/wrapper.exe复制到agent/bin/下,再将lib复制到agent下,得到目录结构如下 agent |- lib |- wrapper.dll |- wrapper.jar |- conf |- wrapper.conf |- bin |- wrapper.exe |- 一堆bat文件 最后将原有项目的文件复制到bin目录下。 步骤3: 配置agent/conf/wrapper.conf的参数 配置java命令路径 wrapper.java.command=jre/bin/java 配置CLASSPATH路径 (并不会修改全局的环境变量) 若原有项目还依赖其他jar包,均需要添加进来 wrapper.java.classpath.1=../lib/wrapper.jar wrapper.java.classpath.2=. 配置lib路径 wrapper.java.library.path.1=../lib 配置服务的main class (就是原有项目的程序入口类) wrapper.app.parameter.1=agent.Daemon ...

2016-01-05 · 1 min · 119 words · -

java 9

java 9 Java 9 正式发布于 2017 年 9 月 21 日 Java 9 带 来了很多重大的变化。其中最重要的改动是 Java 平台模块系统的引入。 jlink 工具 Java 9中有代表性的项目: Kulla项目 (创建Java REPL) Valhalla项目 (改进Java类型) Jigswa项目 (增加模块化功能) http://www.infoq.com/cn/news/2015/05/Java-9-On-Track-For-2016 https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-9/index.html

2016-01-05 · 1 min · 30 words · -

BCM Body Control Module

BCM Body Control Module http://club.autohome.com.cn/bbs/thread-c-2137-14886528-1.html 车身控制器BCM(Body Control Module) 与其相关的还有ABM (Air Bag Module) 与熟识的ABS模块系统,BCM主要涉及车体中灯,门,窗及车身防盗部分,与其他模块共同承担整车的性能与安全的实现,为驾驶带来更多的智能与舒适。 BCM控制技术的方式 BCM控制技术有三种方式: 分散式、集中式和分布式(总线式)。 目前国内采用分散式 bcm的车型主要是经济型轿车,如、旗云、自由舰、伊兰特、爱丽舍、捷达等;用集中式bcm的车型较少,代表车型有御翔、天籁、颐达、骐达、尊驰、骏捷等;中高档轿车多采用分布式bcm,如帕萨特、途安、雅阁、凯旋、奥迪、速腾、蒙迪欧、皇冠、君威、派朗等。 发展趋势 BCM具有以下发展趋势: 越来越多的车身电子设备在车身得到应用,使得BCM控制对象更多;各电子设备的功能越来越多,各种功能都需要通过BCM来实现,使得BCM功能更加强大;各电子设备之间的信息共享越来越多,一个信息可同时供许多部件使用,要求BCM的数据通信功能越来越强;单一集中式BCM很难完成越来越庞大的功能,使得总线式、网络化BCM成为发展趋势。 CAN总线是一种串行多主站总线,是一种有效支持分布式控制或实时控制的串行通信网络。由于其通信速率高,可靠性好以及价格低廉等特点,使其特别适合汽车系统,所以利用CAN总线技术总线式控制车身电子电器装置是BCM发展的必然趋势。 Lin总线也常常应用于BCM通信中,在通信量不大,速率要求不高的低端控制,如自动雨刮及车门防夹功能的实现都是由lin线完成的,这样即满足了要求,又降低了成本。

2016-01-04 · 1 min · 23 words · -

java exit code

java exit code http://blog.sina.com.cn/s/blog_5396eb53010004sg.html The number is only the status code for the termination of the JVM. It does not effect the actual command. By convention 0 means a normal exit, anything else signifies an abnormal termination. You can actually return any int not just a 1 or 0. A common searching for was found, Exit 1 means that the text you were searching for was not found and Exit 2 means it barfed. To get a handle no the exit status, the env variable "$?" is the return status of the last command. So try this: bash$ cat "SOME_FILE_THAT_DOES_NOT_EXIST" bash$ echo $? and your result should be 1. ...

2015-12-30 · 1 min · 125 words · -

java shutdown hook

java shutdown hook 在线上Java程序中经常遇到进程程挂掉,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码。Java中得ShutdownHook提供了比较好的方案。 JDK在1.3之后提供了Java Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下几种场景被调用: 程序正常退出 使用System.exit() 终端使用Ctrl+C触发的中断 系统关闭 使用Kill pid命令干掉进程 注: 在使用kill -9 pid是不会JVM注册的钩子不会被调用。 http://blog.csdn.net/hemingwang0902/article/details/6207682 http://www.cnblogs.com/nexiyi/p/java_add_ShutdownHook.html

2015-12-30 · 1 min · 19 words · -

tightvnc, tigervnc

tightvnc, tigervnc tighervnc nightly build https://github.com/TigerVNC/tigervnc/releases http://tigervnc.bphinz.com/nightly/ # archlinux pacman -S tigervnc # vncserver # dell desktop vncserver -geometry 1350x670 -dpi 96 -depth 32 :1 vncserver -geometry 1364x768 -dpi 96 -depth 32 :1 vncserver -kill :1 #kill 后面有空格!!! vncviewer 192.168.2.228:1 #edis config file .vnc/xstartup #!/bin/sh startxfce4 exit full screen ctrl+alt+shift+F vncviewer: disable allow jpeg https://unix.stackexchange.com/questions/67096/xterm-warning-tried-to-connect-to-session-manager centos yum -y install tigervnc-server yum -y install tigervnc install xorg start xorg install xfce4 ...

2015-12-25 · 1 min · 74 words · -

apache ab/Apache Bench

apache ab/Apache Bench ApacheBench install yay -S apache-tools sudo yum -y install httpd-tools 格式: ab [options] [http://]hostname[:port]/path # get 请求, 不带 -p参数时 发get请求 ab -n 1 -c 1 -T 'application/x-www-form-urlencoded' "http://127.0.0.1:7000/" #post 请求 ab -n 1 -c 1 -p abpost.txt -T 'application/x-www-form-urlencoded' "http://127.0.0.1:7000/" ab -n 1 -c 1 -p abpost.txt -T 'application/json' "http://127.0.0.1:8080/" 参数: -n requests Number of requests to perform //在测试会话中所执行的请求个数 (本次测试总共要访问页面的次数) 。默认时,仅执行一个请求。 -c concurrency Number of multiple requests to make //一次产生的请求个数 (并发数) 。默认是一次一个。 -t timelimit Seconds to max. wait for responses ...

2015-12-25 · 2 min · 350 words · -

ConcurrentHashMap Collections.synchronizedMap

ConcurrentHashMap Collections.synchronizedMap ConcurrentHashMap, Collections.synchronizedMap和Hashtable讨论 在Java类库中出现的第一个关联的集合类是Hashtable,它是JDK1.0的一部分。 Hashtable提供了一种易于使用的、线程安全的、关联的map功能,这当然也是方便的。然而,线程安全性是凭代价换来的――Hashtable的所有方法都是同步的。此时,无竞争的同步会导致可观的性能代价。Hashtable的后继者HashMap是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的基类和一个同步的包装器Collections.synchronizedMap,解决了线程安全性问题。 通过将基本的功能从线程安全性中分离开来,Collections.synchronizedMap允许需要同步的用户可以拥有同步,而不需要同步的用户则不必为同步付出代价。Hashtable和synchronizedMap所采取的获得同步的简单方法 (同步Hashtable中或者同步的Map包装器对象中的每个方法) 有两个主要的不足。首先,这种方法对于可伸缩性是一种障碍,因为一次只能有一个线程可以访问hash表。同时,这样仍不足以提供真正的线程安全性,许多公用的混合操作仍然需要额外的同步。 虽然诸如get()和put()之类的简单操作可以在不需要额外同步的情况下安全地完成,但还是有一些公用的操作序列,例如迭代或者put-if-absent (空则放入) ,需要外部的同步,以避免数据争用。有条件的线程安全性同步的集合包装器 synchronizedMap和synchronizedList,有时也被称作有条件地线程安全――所有单个的操作都是线程安全的,但是多个操作组成的操作序列却可能导致数据争用,因为在操作序列中控制流取决于前面操作的结果。 如果一个条目不在Map中,那么添加这个条目。不幸的是,在 containsKey()方法返回到put()方法被调用这段时间内,可能会有另一个线程也插入一个带有相同键的值。如果您想确保只有一次插入,您需要用一个对Map进行同步的同步块将这一对语句包装起来。List.size()的结果在循环的执行期间可能会变得无效,因为另一个线程可以从这个列表中删除条目。可能在进入循环的最后一次迭代之后有一个条目被另一个线程删除了,则List.get()将返回null,抛出一个 NullPointerException异常。那么,采取什么措施才能避免这种情况呢?如果当您正在迭代一个List时另一个线程也可能正在访问这个 List,那么在进行迭代时您必须使用一个synchronized块将这个List包装起来,在List上同步,从而锁住整个List。 这样做虽然解决了数据争用问题,但是在并发性方面付出了更多的代价,因为在迭代期间锁住整个List会阻塞其他线程,使它们在很长一段时间内不能访问这个列表。集合框架引入了迭代器,用于遍历一个列表或者其他集合,从而优化了对一个集合中的元素进行迭代的过程。然而,在java.util集合类中实现的迭代器极易崩溃,也就是说,如果在一个线程正在通过一个Iterator遍历集合时,另一个线程也来修改这个集合,那么接下来的 Iterator.hasNext()或Iterator.next()调用,会抛出ConcurrentModificationException异常。 如果想要防止出现ConcurrentModificationException异常,那么当您正在进行迭代时,您必须使用一个在 Listl上同步的synchronized块将该List包装起来,从而锁住整个List。 (也可以调用List.toArray(),在不同步的情况下对数组进行迭代,但是如果列表比较大的话这样做代价很高) 。 而ConcurrentHashMap是DougLea的util.concurrent包的一部分,现已被集成到 JDK5.0中,它提供比Hashtable或者synchronizedMap更高程度的并发性。而且,对于大多数成功的get()操作它会设法避免完全锁定,其结果就是使得并发应用程序有着非常好的吞吐量。 1 针对吞吐量进行优化 ConcurrentHashMap使用了几个技巧来获得高程度的并发以及避免锁定,包括为不同的hashbucket (桶) 使用多个写锁和使用 JMM 的不确定性来最小化锁被保持的时间——或者根本避免获取锁。对于大多数一般用法来说它是经过优化的,这些用法往往会检索一个很可能在map中已经存在的值。事实上,多数成功的get()操作根本不需要任何锁定就能运行。 (警告: 不要自己试图这样做!想比 JMM 聪明不像看上去的那么容易。util.concurrent类是由并发专家编写的,并且在 JMM 安全性方面经过了严格的同行评审。) 2 多个写锁 我们可以回想一下,Hashtable (或者替代方案 Collections.synchronizedMap) 的可伸缩性的主要障碍是它使用了一个map范围 (map-wide) 的锁,为了保证插入、删除或者检索操作的完整性必须保持这样一个锁,而且有时候甚至还要为了保证迭代遍历操作的完整性保持这样一个锁。这样一来,只要锁被保持,就从根本上阻止了其他线程访问Map,即使处理器有空闲也不能访问,这样大大地限制了并发性。 ConcurrentHashMap摒弃了单一的map范围的锁,取而代之的是由32个锁组成的集合,其中每个锁负责保护hashbucket的一个子集。锁主要由变化性操作 (put()和remove()) 使用。具有32 个独立的锁意味着最多可以有32个线程可以同时修改map。这并不一定是说在并发地对map进行写操作的线程数少于32时,另外的写操作不会被阻塞—— 32对于写线程来说是理论上的并发限制数目,但是实际上可能达不到这个值。但是,32依然比1要好得多,而且对于运行于目前这一代的计算机系统上的大多数应用程序来说已经足够了。 3 map范围的操作 有32个独立的锁,其中每个锁保护hashbucket的一个子集,这样需要独占访问 map的操作就必须获得所有32个锁。一些map范围的操作,比如说size()和isEmpty(),也许能够不用一次锁整个map (通过适当地限定这些操作的语义) ,但是有些操作,比如map重排 (扩大hashbucket的数量,随着map的增长重新分布元素) ,则必须保证独占访问。Java语言不提供用于获取可变大小的锁集合的简便方法。必须这么做的情况很少见,一旦碰到这种情况,可以用递归方法来实现。 JMM概述 在进入 put()、get()和remove()的实现之前,让我们先简单地看一下 JMM。JMM 掌管着一个线程对内存的动作 (读和写) 影响其他线程对内存的动作的方式。由于使用处理器寄存器和预处理cache来提高内存访问速度带来的性能提升,Java语言规范 (JLS) 允许一些内存操作并不对于所有其他线程立即可见。有两种语言机制可用于保证跨线程内存操作的一致性——synchronized和volatile。 按照JLS的说法,“在没有显式同步的情况下,一个实现可以自由地更新主存,更新时所采取的顺序可能是出人意料的。“其意思是说,如果没有同步的话,在一个给定线程中某种顺序的写操作对于另外一个不同的线程来说可能呈现出不同的顺序,并且对内存变量的更新从一个线程传播到另外一个线程的时间是不可预测的。 虽然使用同步最常见的原因是保证对代码关键部分的原子访问,但实际上同步提供三个独立的功能——原子性、可见性和顺序性。原子性非常简单——同步实施一个可重入的 (reentrant) 互斥,防止多于一个的线程同时执行由一个给定的监视器保护的代码块。不幸的是,多数文章都只关注原子性方面,而忽略了其他方面。但是同步在JMM中也扮演着很重要的角色,会引起JVM在获得和释放监视器的时候执行内存壁垒 (memorybarrier) 。 ...

2015-12-24 · 1 min · 83 words · -

Fluent Interface, fluent manner, fluent 风格, 流式接口, 流式风格

Fluent Interface, fluent manner, fluent 风格, 流式接口, 流式风格 这个故事是从下面这样一个对外暴露接口的调用开始的。 queryUserEvent event = new QueryUserEvent(); event.setName(name); event.setAge(18); event.setType(QueryUserEvent.TYPE_NORMAL); event.setSex(QueryUserEvent.SEX_MALE); //... List<User> userList = userService.query(event); 我想做的事情其实很简单,我想查询一个用户列表,可是接口参数的拼装让我感到头疼,这样的代码太过啰嗦,我希望有可读性更好的解决办法。 P兄台说,如果我直接传入一个user对象,是不是可以避开了这个未必带来多少好处的event? User user = new User(); user.setName(name); user.setAge(18); user.setSex(QueryUserEvent.SEX_MALE); // …… List<User> userList = userService.query(user, UserService.QUERY_TYPE_NORMAL); 我有时候会考虑你说的办法的,可是,你没有解决实际的问题,我现在的最大问题在于,这一堆的setXXX方法,它破坏了我构造这个查询条件对象的流畅性。 他紧接着说,那要不然,我们把setXXX方法的劳动省下来,让构造器来替我们完成这个任务吧: User user = new User(name, 18, QueryUserEvent.SEX_MALE, ……); List<User> userList = userService.query(user, UserService.QUERY_TYPE_NORMAL); 我说,你的办法看起来不错,不过有时候按你的办法做,我的构造方法会变得臃肿无比,比如出现十多个参数; 另外还有一个问题,假如说,我的查询条件是简单的 (我只需要根据年龄查询) ,那么其它的参数都要写成null,类似这样子: User user = new User(null, 18, null, null, null, null, ……); List<User> userList = userService.query(user, UserService.QUERY_TYPE_NORMAL); 天,让谁去阅读这样的代码,他都不会喜欢的。 ...

2015-12-23 · 1 min · 205 words · -

Curator

Curator http://macrochen.iteye.com/blog/1366136 Curator 是 Netflix 开源的一套 ZooKeeper 客户端框架. Netflix 在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情, 于是在它的基础上包装了一下, 提供了一套更好用的客户端框架. Netflix在用ZooKeeper的过程中遇到的问题, 我们也遇到了, 所以开始研究一下, 首先从他在github上的源码, wiki文档以及Netflix的技术blog入手. 看完官方的文档之后, 发现Curator主要解决了三类问题: 封装ZooKeeper client与ZooKeeper server之间的连接处理; 提供了一套Fluent风格的操作API; 提供ZooKeeper各种应用场景(recipe, 比如共享锁服务, 集群领导选举机制)的抽象封装. Curator列举的ZooKeeper使用过程中的几个问题 初始化连接的问题: 在client与server之间握手建立连接的过程中, 如果握手失败, 执行所有的同步方法(比如create, getData等)将抛出异常 自动恢复(failover)的问题: 当client与一台server的连接丢失,并试图去连接另外一台server时, client将回到初始连接模式 session过期的问题: 在极端情况下, 出现ZooKeeper session过期, 客户端需要自己去监听该状态并重新创建ZooKeeper实例 . 对可恢复异常的处理:当在server端创建一个有序ZNode, 而在将节点名返回给客户端时崩溃, 此时client端抛出可恢复的异常, 用户需要自己捕获这些异常并进行重试 使用场景的问题:Zookeeper提供了一些标准的使用场景支持, 但是ZooKeeper对这些功能的使用说明文档很少, 而且很容易用错. 在一些极端场景下如何处理, zk并没有给出详细的文档说明. 比如共享锁服务, 当服务器端创建临时顺序节点成功, 但是在客户端接收到节点名之前挂掉了, 如果不能很好的处理这种情况, 将导致死锁. Curator主要从以下几个方面降低了zk使用的复杂性: 重试机制:提供可插拔的重试机制, 它将给捕获所有可恢复的异常配置一个重试策略, 并且内部也提供了几种标准的重试策略(比如指数补偿). 连接状态监控: Curator初始化之后会一直的对zk连接进行监听, 一旦发现连接状态发生变化, 将作出相应的处理. zk客户端实例管理:Curator对zk客户端到server集群连接进行管理. 并在需要的情况, 重建zk实例, 保证与zk集群的可靠连接 各种使用场景支持:Curator实现zk支持的大部分使用场景支持(甚至包括zk自身不支持的场景), 这些实现都遵循了zk的最佳实践, 并考虑了各种极端情况. ...

2015-12-23 · 3 min · 613 words · -

Paxos

Paxos paxos Paxos (Greek: Παξοί, pronounced Paksi in English ) 又名Paxi是希腊西南部一个风景如画的小岛。而Paxos算法则是现在很火的分布式一致性算法,为何以一个希腊小岛名字算法?Lamport这样解释道: I thought, and still think, that Paxos is an important algorithm. Inspired by my success at popularizing the consensus problem by describing it with Byzantine generals, I decided to cast the algorithm in terms of a parliament on an ancient Greek island. Leo Guibas suggested the name Paxos for the island. 为描述 Paxos 算法,Lamport 虚拟了一个叫做 Paxos 的希腊城邦,这个岛按照议会民主制的政治模式制订法律,但是没有人愿意将自己的全部时间和精力放在这种事情上。所以无论是议员,议长或者传递纸条的服务员都不能承诺别人需要时一定会出现,也无法承诺批准决议或者传递消息的时间。但是这里假设没有拜占庭将军问题 (Byzantine failure,即虽然有可能一个消息被传递了两次,但是绝对不会出现错误的消息) ;只要等待足够的时间,消息就会被传到。另外,Paxos 岛上的议员是不会反对其他议员提出的决议的[1]。 ...

2015-12-23 · 1 min · 99 words · -