??xml version="1.0" encoding="utf-8" standalone="yes"?>
一般的服务器都需要线E池Q比如Web、FTP{服务器Q不q它们一般都自己实现?jin)线E池Q比如以前介l过的Tomcat、Resin和Jetty{,现在有了(jin)JDK5Q我们就没有必要重复造R轮了(jin)Q直接用就可以Q何况用也很方便,性能也非帔R?
上面是一个简单的例子Q用了(jin)2个大的U程池来处理100个线E。但有一个问题:(x)在for循环的过E中Q会(x){待U程池有I闲的线E,所以主U程
?x)阻塞的。ؓ(f)?jin)解册个问题,一般启动一个线E来做for循环Q就是ؓ(f)?jin)避免由于线E池满了(jin)造成ȝE阻塞。不q在q里我没有这样处理。[重要修正Q经q?
试Q即使线E池大小于实际U程数大,U程池也不会(x)d的,q与Tomcat的线E池不同Q它?yu)Runnable实例攑ֈ一?#8220;无限”?
BlockingQueue中,所以就不用一个线E启动for循环QDoug Lea果然厉害]
另外它用了(jin)Executors的静(rn)态函数生成一个固定的U程池,思义Q线E池的线E是不会(x)释放的,即它是Idle。这׃(x)产生性能问题Q?
比如如果U程池的大小?00Q当全部使用完毕后,所有的U程?x)l留在池中,相应的内存和U程切换Qwhile(true)+sleep循环Q都?x)?
加。如果要避免q个问题Q就必须直接使用ThreadPoolExecutor()来构造。可以像Tomcat的线E池一栯|?#8220;最大线E数”?#8220;最线
E数”?#8220;I闲U程keepAlive的时?#8221;。通过q些可以基本上替换Tomcat的线E池实现Ҏ(gu)?
需要注意的是线E池必须使用shutdown来显式关闭,否则ȝE就无法退出。shutdown也不?x)阻塞主U程?
许多长时间运行的应用有时候需要定时运行Q务完成一些诸如统计、优化等工作Q比如在?sh)信行业中处理用戯单时Q需要每?分钟处理话单Q网站每?
凌晨l计用户讉K量、用hQ大型超时凌?点统计当天销售额、以?qing)最热卖的商品;每周日进行数据库备䆾Q公司每个月?0可工资ƈq行转帐{,q些
都是定时d。通过 java的ƈ发库concurrent可以L的完成这些Q务,而且非常的简单?
Z(jin)退?gu)E,上面的代码中加入?jin)关闭Scheduler的操作。而对?4时q行的应用而言Q是没有必要关闭Scheduler的?
在实际应用中Q有时候需要多个线E同时工作以完成同一件事情,而且在完成过E中Q往往?x)等待其他线E都完成某一阶段后再执行Q等所有线E都到达某一个阶D后再统一执行?
比如有几个旅行团需要途经深圳、广州、韶兟뀁长沙最后到达武汉。旅行团中有自驾游的Q有徒步的,有乘坐旅游大巴的Q这些旅行团同时出发Qƈ且每C个目的地Q都要等待其他旅行团到达此地后再同时出发Q直到都到达l点站武汉?
q时候C(j)yclicBarrier可以派上用场。CyclicBarrier最重要的属性就是参与者个敎ͼ另外最要方法是await()。当所有线E都调用?jin)await()后,pC些线E都可以l箋(hu)执行Q否则就?x)等待?
q行l果Q?
00:02:25: SelfTour Reached Shenzhen
00:02:25: BusTour Reached Shenzhen
00:02:27: WalkTour Reached Shenzhen
00:02:30: SelfTour Reached Guangzhou
00:02:31: BusTour Reached Guangzhou
00:02:35: WalkTour Reached Guangzhou
00:02:39: SelfTour Reached Shaoguan
00:02:41: BusTour Reached Shaoguan
q发库中的BlockingQueue是一个比较好玩的c,思义Q就是阻塞队列。该cM要提供了(jin)两个Ҏ(gu)put()和take()Q前者将一
个对象放到队列中Q如果队列已l满?jin),q待直到有I闲节点Q后者从head取一个对象,如果没有对象Q就{待直到有可取的对象?
下面的例子比较简单,一个读U程Q用于将要处理的文g对象d到阻塞队列中Q另外四个写U程用于取出文g对象Qؓ(f)?jin)模拟写操作耗时长的特点Q特?
U程睡眠一D随机长度的旉。另外,该Demo也用到?jin)线E池和原子整型(AtomicIntegerQ,AtomicInteger可以在ƈ发情况下
辑ֈ原子化更斎ͼ避免使用?jin)synchronizedQ而且性能非常高。由于阻塞队列的put和take操作?x)阻塞,Z(jin)使线E退出,特在队列中添加了(jin)一
?#8220;标识”Q算法中也叫“哨兵”Q当发现q个哨兵后,写线E就退出?
当然U程池也要显式退Z(jin)?
从名字可以看出,CountDownLatch是一个倒数计数的锁Q当倒数?时触发事Ӟ也就是开锁,其他人就可以q入?jin)。在一些应用场合中Q需要等待某个条件达到要求后才能做后面的事情Q同时当U程都完成后也会(x)触发事gQ以便进行后面的操作?
CountDownLatch最重要的方法是countDown()和await()Q前者主要是倒数一ơ,后者是{待倒数?Q如果没有到?Q就只有d{待?jin)?
一个CountDouwnLatch实例是不能重复用的Q也是说它是一ơ性的Q锁一l被打开׃能再关闭使用?jin),如果想重复用,误(g)虑使用CyclicBarrier?
下面的例子简单的说明?jin)CountDownLatch的用方法,模拟?00c跑,10名选手已经准备qAQ只{裁判一Co(h)下。当所有h都到辄Ҏ(gu)Q比赛结束?
同样Q线E池需要显式shutdown?
q行l果:
Game Start
No.4 arrived
No.1 arrived
No.7 arrived
No.9 arrived
No.3 arrived
No.2 arrived
No.8 arrived
No.10 arrived
No.6 arrived
No.5 arrived
Game Over
有时候在实际应用中,某些操作很耗时Q但又不是不可或~的步骤。比如用|页览器浏览新LQ最重要的是要显C文字内容,至于与新ȝ匚w的图?
没有那么重要的Q所以此旉先保证文字信息先昄Q而图片信息会(x)后显C,但又不能不显C,׃下蝲囄是一个耗时的操作,所以必M开始就得下载?
Java的ƈ发库的Futurecd可以满q个要求。Future的重要方法包括get()和cancel()Qget()获取数据对象Q如?
数据没有加蝲Q就?x)阻塞直到取到数据,?
cancel()是取消数据加载。另外一个get(timeout)操作Q表C如果在timeout旉内没有取到就p|q回Q而不再阻塞?
下面的Demo单的说明?jin)Future的用方法:(x)一个非常耗时的操作必M开始启动,但又不能一直等待;其他重要的事情又必须做,{完成后Q就可以做不重要的事情?
q行l果Q?
Let’s do important things.
Other less important but longtime things.
考虑以下场景Q浏览网|Q浏览器?个线E下载网中的图片文Ӟ׃囄大小、网站访问速度{诸多因素的影响Q完成图片下载的旉׃(x)有很大的不同。如果先下蝲完成的图片就?x)被先显C到界面上,反之Q后下蝲的图片就后显C?
Java的ƈ发库的CompletionService可以满q种场景要求。该接口有两个重要方法:(x)submit()和take()?
submit用于提交一个runnable或者callableQ一般会(x)提交l一个线E池处理Q而take是取出已经执行完毕r(sh)unnable或?
callable实例的Future对象Q如果没有满求的Q就{待?jin)?
CompletionServiceq有一个对应的Ҏ(gu)pollQ该Ҏ(gu)与takecMQ只是不?x)等待,如果没有满要求Q就q回null对象?
q行l果:
Show web content
Downloaded Image 1
Downloaded Image 2
Downloaded Image 4
Downloaded Image 0
Downloaded Image 3
End
操作pȝ的信号量是个很重要的概念Q在q程控制斚w都有应用。Javaq发库的Semaphore可以很轻村֮成信号量控制QSemaphore
可以控制某个资源可被同时讉K的个敎ͼacquire()获取一个许可,如果没有q待,而release()释放一个许可。比如在Windows下可?
讄׃n文g的最大客L(fng)讉K个数?
Semaphorel护?jin)当前访问的个数Q提供同步机Ӟ控制同时讉K的个数。在数据l构中链表可以保?#8220;无限”的节点,用Semaphore可以实现有限大小的链表。另外重入锁ReentrantLock也可以实现该功能Q但实现上要负责些,代码也要复杂些?
下面的Demo中申明了(jin)一个只?个许可的SemaphoreQ而有20个线E要讉Kq个资源Q通过acquire()和release()获取和释放访问许可?
q行l果Q?
Accessing: 0
Accessing: 1
Accessing: 2
Accessing: 3
Accessing: 4
Accessing: 5
Accessing: 6
Accessing: 7
Accessing: 8
Accessing: 9
Accessing: 10
Accessing: 11
Accessing: 12
Accessing: 13
Accessing: 14
Accessing: 15
Accessing: 16
Accessing: 17
Accessing: 18
Accessing: 19
]]>
Sun HotSpot 1.4.1 JVM堆大的调整
Sun
HotSpot
1.4.1使用分代攉器,它把堆分Z个主要的域:(x)新域、旧域以?qing)永久域。Jvm生成的所有新对象攑֜新域中。一旦对象经历了(jin)一定数量的垃圾攉循环
后,便获得用期q进入旧域。在怹域中jvm则存储class和method对象。就配置而言Q永久域是一个独立域q且不认为是堆的一部分?br />
下面介绍如何控制q些域的大小。可使用-Xms?Xmx 控制整个堆的原始大小或最大倹{?br />
下面的命令是把初始大设|ؓ(f)128MQ?br />
java –Xms128m
–Xmx256m为控制新域的大小Q可使用-XX:NewRatio讄新域在堆中所占的比例?br />
下面的命令把整个堆设|成128mQ新域比率设|成3Q即新域与旧域比例ؓ(f)1Q?Q新域ؓ(f)堆的1/4?2MQ?br />
java –Xms128m –Xmx128m
–XX:NewRatio =3可?XX:NewSize?XX:MaxNewsize讄新域的初始值和最大倹{?br />
下面的命令把新域的初始值和最大D|成64m:
java –Xms256m –Xmx256m –Xmn64m
怹域默认大ؓ(f)4m。运行程序时Qjvm?x)调整永久域的大以满需要。每ơ调整时Qjvm?x)对堆进行一ơ完全的垃圾攉?br />
使用-XX:MaxPerSize标志来增加永久域搭大。在WebLogic
Server应用E序加蝲较多cLQ经帔R要增加永久域的最大倹{当jvm加蝲cLQ永久域中的对象急剧增加Q从而jvm不断调整怹域大。ؓ(f)?jin)避?
调整Q可使用-XX:PerSize标志讄初始倹{?br />
下面把永久域初始D|成32mQ最大D|成64m?br />
java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m
默认状态下QHotSpot在新域中使用复制攉器。该域一般分Z个部分。第一部分为EdenQ用于生成新的对象。另两部分称为救助空_(d)当Eden?
满时Q收集器停止应用E序Q把所有可到达对象复制到当前的from救助I间Q一旦当前的from救助I间充满Q收集器则把可到辑֯象复制到当前的to救助
I间。From和to救助I间互换角色。维持活动的对象在救助I间不断复制Q直到它们获得用期q{入旧域。?XX:SurvivorRatio?
控制新域子空间的大小?br />
同NewRation一PSurvivorRation规定某救助域与EdenI间的比倹{比如,以下命o(h)把新域设|成64mQEden?2mQ每个救助域各占16mQ?br />
java -Xms256m -Xmx256m -Xmn64m -XX:SurvivorRation =2
如前所qͼ默认状态下HotSpotҎ(gu)域用复制收集器Q对旧域使用标记Q清除-压羃攉器。在新域中用复制收集器有很多意义,因ؓ(f)应用E序生成的大
部分对象是短寿命的。理想状态下Q所有过渡对象在UdEdenI间时将被收集。如果能够这L(fng)话,q且UdEdenI间的对象是长寿命的Q那么理Z可以
立即把它们移q旧域,避免在救助空间反复复制。但是,应用E序不能适合q种理想状态,因ؓ(f)它们有一部分中长寿命的对象。最好是保持q些中长寿命的对象ƈ
攑֜新域中,因ؓ(f)复制部分的对象L压羃旧域廉h(hun)。ؓ(f)控制新域中对象的复制Q可?XX:TargetSurvivorRatio控制救助I间的比?
Q该值是讄救助I间的用比例。如救助I间?MQ该?0表示可用500KQ。该值是一个百分比Q默认值是50。当较大的堆栈用较低的
sruvivorratioӞ应增加该值到80?0Q以更好利用救助I间。用-XX:maxtenuring threshold可控制上限?br />
为放|所有的复制全部发生以及(qing)希望对象从eden扩展到旧域,可以把MaxTenuring Threshold讄?。设|完成后Q实际上׃再用救助空间了(jin)Q因此应把SurvivorRatio设成最大g最大化EdenI间Q设|如下:(x)
java … -XX:MaxTenuringThreshold=0 –XX:SurvivorRatioQ?0000 …
]]>
备忘录缓存方案一Q?
q里备忘录的整个computeq程被同步,相当于我最原始的低效方案,
备忘录缓存方案二Q?
线E安全性委lcacheQ注Q这个方案的cache用了(jin)ConcurrentHashMapQ它是线E安全的?
备忘录缓存方案三Q?
使用Future(相当上一帖的Entry)装Q因里资源获取过E不固定(通用Ҏ(gu))Q所以用了(jin)Callableq行回调资源获取q程(求?Q?
q个Ҏ(gu)?if (f == null) 不安全,Ҏ(gu)性可能会(x)q行多次q算Q下面的Ҏ(gu)四解册个问题?
备忘录缓存方案四Q最l方案)(j)Q?
]]>
1、OSCache是什?
OSCache标记库由O(jin)penSymphony设计Q它是一U开创性的~存Ҏ(gu)Q它提供?jin)在现有JSP面之内实现内存~存的功能。OSCache是个
一个被q泛采用的高性能的J2EE~存框架QOSCacheq能应用于Q何Java应用E序的普通的~存解决Ҏ(gu)?br />
2、OSCache的特?/strong>
(1) ~存?sh)M对象Q你可以不受限制的缓存部分jsp面或HTTPhQQ何java对象都可以缓存?br />
(2) 拥有全面的APIQOSCache API允许你通过~程的方式来控制所有的OSCacheҎ(gu)?
(3) 怹~存Q缓存能被配|写入硬盘,因此允许在应用服务器的多ơ生命周期间~存创徏开销昂贵的数据?
(4) 支持集群Q集缓存数据能被单个的q行参数配置Q不需要修改代码?br />
(5) ~存q期Q你可以有最大限度的控制~存对象的过期,包括可插入式的刷新策略(如果默认性能不能满需要时Q?br />
3、OSCache的安装与配置
|上已经有一个不错的使用教程Q?a target="_blank">http://blog.csdn.net/ezerg/archive/2004/10/14/135769.aspx
4、有?#8220;用OSCacheq行~存对象”的研I?/strong>
q个是我今天要说的东ѝ网上对于OSCache~存Web面很多说明和例子,但对于缓存对象方面说得不多,我就把自已写得一些东西放出来Q让大家看一看是怎样~存对象?
我基于GeneralCacheAdministratorcL写的BaseCachec?br />
通过CacheManagercL看怎样~存对象?q个cM所用的News只是具体功能的类Q我׃贴出来了(jin)Q你可以自己写一?
]]>
format(Locale l, String format, Object... args) 使用指定的语a环境、格式字W串和参数返回一个格式化字符丌Ӏ?br />
format(String format, Object... args) 使用指定的格式字W串和参数返回一个格式化字符丌Ӏ?br />
丑և个这个方法实用的例子(注释是输出结?Q?
CODE:
long now = System.currentTimeMillis();
String s = String.format("%tR", now); // "15:12"
CODE:
// Current month/day/year
Date d = new Date(now);
s = String.format("%tD", d); // "07/13/04"
CODE:
s = String.format("%,d", Integer.MAX_VALUE); // "2,147,483,647"
CODE:
s = String.format("%05d", 123); // "00123"
是不是很方便Q让人动?j)啊Q哈哈,q有更多的效?
?
实format函数有些cMc语言中printf函数Q一些格式字W串?C cMQ但已进行了(jin)某些定制Q以适应 Java
语言Qƈ且利用了(jin)其中一些特性。此Ҏ(gu)提供?jin)对布局寚w和排列的支持Q以?qing)对数倹{字W串和日?旉数据的常规格式和特定于语a环境的输出的支持。支?
诸如 byte、BigDecimal ?Calendar {常?Java cd?br />
产生格式化输出的每个Ҏ(gu)都需要格式字W串 和参数列表。格式字W串是一?StringQ它可以包含固定文本以及(qing)一个或多个嵌入的格式说明符。请考虑以下CZQ?br />
Calendar c = ...;
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
?
式字W串?format Ҏ(gu)的第一个参数。它包含三个格式说明W?"%1$tm"?%1$te" ?
"%1$tY"Q它们指出应该如何处理参C?qing)在文本的什么地Ҏ(gu)入它们。格式字W串的其余部分是包括 "Dukes Birthday: "
和其他Q何空格或标点W号的固定文本?参数列表׃递给位于格式字符串之后的Ҏ(gu)的所有参数组成。在上述CZ中,参数列表的大ؓ(f) 1Q由新对?
Calendar l成?br />
1.常规cd、字W类型和数值类型的格式说明W的语法如下Q?/strong>%[argument_index$][flags][width][.precision]conversion
可选的 argument_index 是一个十q制整数Q用于表明参数在参数列表中的位置。第一个参数由 "1$" 引用Q第二个参数?"2$" 引用Q依此类推?br />
可选的 flags 是修改输出格式的字符集。有效标志的集合取决于{换类型?br />
可?width 是一个非负十q制整数Q表明要向输Z写入的最字W数?br />
可?precision 是一个非负十q制整数Q通常用来限制字符数。特定行为取决于转换cd?br />
所需?conversion 是一个表明应该如何格式化参数的字W。给定参数的有效转换集合取决于参数的数据cd?br />
2.用来表示日期和时间类型的格式说明W的语法如下:
%[argument_index$][flags][width]conversion
可选的 argument_index?em>flags ?width 的定义同上?br />
所需?conversion 是一个由两字W组成的序列。第一个字W是 't' ?'T'。第二个字符表明所使用的格式。这些字W类g但不完全{同于那些由 GNU date ?POSIX strftime(3c) 定义的字W?
3.与参C对应的格式说明符的语法如下:(x)
%[flags][width]conversion
可?flags ?width 的定义同上?br />
所需?conversion 是一个表明要在输Z所插内容的字符?
转换
转换可分Z下几c:(x)
1. 常规 - 可应用于M参数cd
2.
字符 - 可应用于表示 Unicode 字符的基本类型:(x)char、Character、byte、Byte、short ?Short。当
Character.isValidCodePoint(int) q回 true Ӟ可将此{换应用于 int ?Integer cd
3. 数?br />
1. 整数 - 可应用于 Java 的整数类型:(x)byte、Byte、short、Short、int、Integer、long、Long ?BigInteger
2. 点 - 可用?Java 的Q点类型:(x)float、Float、double、Double ?BigDecimal
4. 日期/旉 - 可应用于 Java 的、能够对日期或时间进行编码的cdQlong、Long、Calendar ?Date?br />
5. 癑ֈ?- 产生字面?'%' ('"u0025')
6. 行分隔符 - 产生特定于^台的行分隔符
?
表ȝ?jin)受支持的{换。由大写字符Q如 'B'?H'?S'?C'?X'?E'?G'?A' ?
'T'Q表C的转换与由相应的小写字W的转换{同Q根据流行的 Locale 规则结果{换ؓ(f)大写形式除外。后者等同于
String.toUpperCase() 的以下调?
转换 | 参数cd | 说明 |
'b', 'B' | 常规 | 如果参数 arg ?nullQ则l果?"false"。如?arg 是一?boolean 值或 BooleanQ则l果?String.valueOf() q回的字W串。否则结果ؓ(f) "true"?/td> |
'h', 'H' | 常规 | 如果参数 arg ?nullQ则l果?"null"。否则,l果?Integer.toHexString(arg.hashCode()) 得到的结果?/td> |
's', 'S' | 常规 | 如果参数 arg ?nullQ则l果?"null"。如?arg 实现 FormattableQ则调用 arg.formatTo。否则,l果?arg.toString() 得到的结果?/td> |
'c', 'C' | 字符 | l果是一?Unicode 字符 |
'd' | 整数 | l果被格式化为十q制整数 |
'o' | 整数 | l果被格式化为八q制整数 |
'x', 'X' | 整数 | l果被格式化为十六进制整?/td> |
'e', 'E' | 点 | l果被格式化为用计算机科学记数法表示的十q制?/td> |
'f' | 点 | l果被格式化为十q制?/td> |
'g', 'G' | 点 | Ҏ(gu)_ֺ和舍入运后的|使用计算机科学记数Ş式或十进制格式对l果q行格式化?/td> |
'a', 'A' | 点 | l果被格式化为带有效位数和指数的十六q制点?/td> |
't', 'T' | 日期/旉 | 日期和时间{换字W的前缀。请参阅日期/旉转换?/td> |
'%' | 癑ֈ? | l果为字面?'%' ('"u0025') |
'n' | 行分隔符 | l果为特定于q_的行分隔W?/td> |
'H' | 24 时制的时Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 23?/td> |
'I' | 12 时制的时Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?01 - 12?/td> |
'k' | 24 时制的时Q即 0 - 23?/td> |
'l' | 12 时制的时Q即 1 - 12?/td> |
'M' | 时中的分钟Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 59?/td> |
'S' | 分钟中的U,被格式化为必要时带前导零的两位数Q即 00 - 60 Q?60" 是支持闰U所需的一个特D|(j)?/td> |
'L' | U中的毫U,被格式化为必要时带前导零的三位数Q即 000 - 999?/td> |
'N' | U中的毫微秒Q被格式化ؓ(f)必要时带前导零的?ji)位敎ͼ?000000000 - 999999999?/td> |
'p' | 特定于语a环境?上午或下?/a> 标记以小写Ş式表C,例如 "am" ?"pm"。用{换前~ 'T' 可以此输出转换为大写Ş式?/td> |
'z' | 相对?GMT ?RFC 822 格式的数字时区偏U量Q例?-0800?/td> |
'Z' | 表示时区~写形式的字W串。Formatter 的语a环境?yu)取代参数的语言环境Q如果有Q?/td> |
's' | 自协调世界时 (UTC) 1970 q?1 ?1 ?00:00:00 至现在所l过的秒敎ͼ?Long.MIN_VALUE/1000 ?Long.MAX_VALUE/1000 之间的差倹{?/td> |
'Q' | 自协调世界时 (UTC) 1970 q?1 ?1 ?00:00:00 至现在所l过的毫U数Q即 Long.MIN_VALUE ?Long.MAX_VALUE 之间的差倹{?/td> |
'B' | 特定于语a环境?a target="_blank">月䆾全称Q例?"January" ?"February"?/td> |
'b' | 特定于语a环境?a target="_blank">月䆾U?/a>Q例?"Jan" ?"Feb"?/td> |
'h' | ?'b' 相同?/td> |
'A' | 特定于语a环境?a target="_blank">星期?/a>全称Q例?"Sunday" ?"Monday" |
'a' | 特定于语a环境?a target="_blank">星期?/a>Uͼ例如 "Sun" ?"Mon" |
'C' | 除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数Q即 00 - 99 |
'Y' | q䆾Q被格式化ؓ(f)必要时带前导零的四位敎ͼ臛_Q,例如Q?092 {于格里高利历的 92 CE?/td> |
'y' | q䆾的最后两位数Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?00 - 99?/td> |
'j' | 一q中的天敎ͼ被格式化为必要时带前导零的三位数Q例如,对于格里高利历是 001 - 366?/td> |
'm' | 月䆾Q被格式化ؓ(f)必要时带前导零的两位敎ͼ?01 - 13?/td> |
'd' | 一个月中的天数Q被格式化ؓ(f)必要时带前导零两位数Q即 01 - 31 |
'e' | 一个月中的天数Q被格式化ؓ(f)两位敎ͼ?1 - 31?/td> |
'R' | 24 时制的旉Q被格式化ؓ(f) "%tH:%tM" |
'T' | 24 时制的旉Q被格式化ؓ(f) "%tH:%tM:%tS"?/td> |
'r' | 12 时制的旉Q被格式化ؓ(f) "%tI:%tM:%tS %Tp"。上午或下午标记 ('%Tp') 的位|可能与语言环境有关?/td> |
'D' | 日期Q被格式化ؓ(f) "%tm/%td/%ty"?/td> |
'F' | ISO 8601 格式的完整日期,被格式化?"%tY-%tm-%td"?/td> |
'c' | 日期和时_(d)被格式化?"%ta %tb %td %tT %tZ %tY"Q例?"Sun Jul 20 16:17:00 EDT 1969"?/td> |
标志 | 常规 | 字符 | 整数 | 点 | 日期/旉 | 说明 |
'-' | y | y | y | y | y | l果是左对齐的?/td> |
'#' | y1 | - | y3 | y | - | l果应该使用依赖于{换类型的替换形式 |
'+' | - | - | y4 | y | - | l果L包括一个符?/td> |
' ' | - | - | y4 | y | - | 对于正|l果中将包括一个前导空?/td> |
'0' | - | - | y | y | - | l果用零来填充 |
',' | - | - | y2 | y5 | - | l果包括特定于语言环境?a target="_blank">l分隔符 |
'(' | - | - | y4 | y5 | - | l果是用圆括号括v来的负数 |
Calendar c = ...;
String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
String s2 = String.format("Duke's Birthday: %1$tm %<$te,%<$tY", c);
源代码:(x)
/**
* @author 沈东?Edward Shen<a href="mailto:shendl_s@hotmail.com">shendl_s@hotmail.com</a>
* 2007-5-23 下午03:11:45
*执行位操?br />
*
*
*/
public class BitUtil {
/**
* 把字节指定的位数设ؓ(f)1Q不原来该位是什么?br />
* @param data
* @param pos ?开?br />
*/
public static byte setByteBitOne(byte data,int pos){
byte compare=(byte) Math.pow(2.0,pos);
data=(byte) (data|compare);
return data;
}
/**
* 把字节指定的位数设ؓ(f)0Q不原来该位是什么?br />
* @param data
* @param pos
*/
public static byte setByteBitZero(byte data,int pos){
byte compare=(byte) ~(byte) Math.pow(2.0,pos);
data=(byte) (data&compare);
return data;
}
/**
* q回指定字节W几个位的数字,只可能是Q或者1
* @param data
* @param pos ?开始的位数
* @return
*/
public static int getByteBit(byte data,int pos){
int bitData = 0;
byte compare=(byte) Math.pow(2.0,pos);
if((data & compare)==compare){
bitData =1;
}
return bitData;
}
/**
* q回一个字节的每一位的数字
* @param data
* @return
*/
public static byte[] getByteBits(byte data){
byte[] results=new byte[8];
for(int i=0;i<8;i++){
results[i]=(byte) BitUtil.getByteBit(data, i);
}
return results;
}
/**
*
*/
public BitUtil() {
/*
*
*/
}
}
class CheckVars {
privateintinstVar;// 成员变量
privatestaticintstaticVar; // ?rn)态变?/span>
// 存取cL法中的(f)时变?/span>
void tempAccess(int val) {
int j = 0;// 临时变量
long startTime = System.currentTimeMillis();
for (int i = 0; i < val; i++)
j += 1;
long endTime = System.currentTimeMillis();
System.out.println("temp var: " + (endTime - startTime) + " milli seconds");
}
// 存取cȝ成员变量
void instanceAccess(int val) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < val; i++)
instVar += 1;
long endTime = System.currentTimeMillis();
System.out.println("instance var: " + (endTime - startTime) + " milli seconds");
}
// 存取cȝ static 变量
void staticAccess(int val) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < val; i++)
staticVar += 1;
long endTime = System.currentTimeMillis();
System.out.println("static var: " + (endTime - startTime) + " milli seconds");
}
publicstaticvoid main(String[] args){
CheckVars test=new CheckVars();
test.tempAccess(200000000);
test.instanceAccess(200000000);
test.staticAccess(200000000);
}
}
|
publicclass CheckVarsAdv {
privateintinstVar;
privatestaticintstaticVar;
void tempAccess(int val) {
int j = 0;
long startTime = System.currentTimeMillis();
for (int i = 0; i < val; i++)
j += 1;
long endTime = System.currentTimeMillis();
System.out.println("temp var: " + (endTime - startTime) + " milli seconds");
}
void instanceAccess(int val) {
int j = instVar;
long startTime = System.currentTimeMillis();
for (int i = 0; i < val; i++)
j += 1;
long endTime = System.currentTimeMillis();
System.out.println("instance var: " + (endTime - startTime) + " milli seconds");
instVar = j;
}
void staticAccess(int val) {
int j = staticVar;
long startTime = System.currentTimeMillis();
for (int i = 0; i < val; i++)
j += 1;
long endTime = System.currentTimeMillis();
System.out.println("static var: " + (endTime - startTime) + " milli seconds");
staticVar = j;
}
publicstaticvoid main(String[] args){
CheckVarsAdv test=new CheckVarsAdv();
test.tempAccess(200000000);
test.instanceAccess(200000000);
test.staticAccess(200000000);
}
}
|
本文?gu)?“??/a>” 博客Q请务必保留此出?a >http://zhangjunhd.blog.51cto.com/113473/49322
用Java~写E序最大的优点在于“一ơ编译,处处q行”Q可是事实上Q相当一部分的JavaE序不能在别的操作系l上正确q行Q最后倒搞成了(jin)“一ơ编写,处处调试”Q那么如何才能编写一个真正的跨^台的JavaE序呢?下面有几个要点要注意Q?
1.你的E序需要是100%UJava的。特别是使用W三方的cd包时一定要注意q一炏V?
2.无论你用的是JDK或其他开发工P在编译时都要打开所有的警告选项Q这L(fng)译器可以可能多的发现^台相关的语句Qƈl出警告。虽然不能保证没有编译时警告的程序一定是跨^台的Q但含有警告的程序却很有可能是非q_无关的?
3.׃JDK是向下兼容的Q因此可以用过时的Ҏ(gu)QDeprecated methodQ,但调试时要打开Qdeprecation选项?/p>
4.退出JavaE序时尽量不要用java.lang.System的exitҎ(gu)。Exit Ҏ(gu)可以l止JVMQ从而终止程序,但如果同时运行了(jin)另一个JavaE序Q用exitҎ(gu)׃(x)让该E序也关闭,q显然不是我们希望看到的情况。事实上? 退出JavaE序Q可以用destory()退Z个独立运行的U程。对于多U程E序Q必要关闭各个非守护线E。只有在E序非正帔R出时Q才使用 exitҎ(gu)退出程序?
5.避免使用本地Ҏ(gu)和本C码,可能自q写具有相应功能的Javac,改写该方法。如果一定要使用该本地方法,可以~写一个服务器E序调用该方法,然后现在要~写的程序作服务器程序的客户E序Q或者考虑CORBAQ公共对象请求代理)(j)E序l构?
6.Java中有一个类gDelphi中的winexec的方法,java.lang.runtimecȝexecҎ(gu)Q作Ҏ(gu)本n是具有^台无 x(chng)的Q但是给Ҏ(gu)所调用的命令及(qing)命o(h)参数却是与^台相关的Q因此,在编写程序时要避免用,如果一定要调用其他的程序的话,必须要让用户自己来设|该? 令及(qing)其参数。比如说Q在windows中可以调用notepad.exeE序Q在linux 中就要调用viE序?jin)?
7.注意q不是所有的操作pȝ都支持Unicode字符集,q对于跨q_的Java中文软gE序不能不说是一大噩耗?
8.在程序中不要性编码与q_相关的Q何常量,比如行分隔符Q文件分隔符Q\径分隔符{等Q这些常量在不同的^C是不同的Q比如文件分隔符Q在 UNIX和MAC中是“/”Q在windows中是“"”Q如果要使用q些帔RQ需要用jdava.util.Propertiescȝ getPropertyҎ(gu)Q如java.util.Properties.getProperty(“file.separator”)可以获得文g? 隔符QgetProperty (“line.separator”)q回行分隔符QgetProperty(“path.separator”)q回路径分隔W?
9.在编写跨q_的网l程序时Q不要用java.net.InetAddresscȝgetHostNameҎ(gu)得到L名,因ؓ(f)不同的^台的L? 格式是不同的Q最好用getAddress得到格式相同的IP地址Q另外,E序中所有的L名都要换成IP地址Q比如www.b9527.netp? 成相应的IP地址?
10.涉及(qing)文g操作的程序需要注意:(x)不要在程序中性编码文件\径,而且不同q_对于文g名用的字符?qing)最大文件名长度的要求不同,~写你的E序的时候要使用一般的ASCII码字W作为文件的名字Q而且不能与^C已存在的E序同名Q否则会(x)造成冲突?
11.如果你写的程序是GUIE序Q在使用AWTlg时不要硬性设|组件的大小和位|而应该用Java的布局理器来讄和管理可视组件的大小和位|,否则有可能造成布局混ؕ?
12.׃不同的操作系l,不同的机器,pȝ支持的颜色和屏幕的大和分L率都不同Q如何获得这些属性呢Q? java.awt.Systemcolorcd以获得需要的颜色Q如该类的inactiveCaption 是H口Ҏ(gu)中活动标题的背景颜色Qmenu则是菜单的背景颜艌Ӏ用java.awt.Toolkit的getScreenResolution可以? “像素每英?#8221;为单位显C屏q的分L率。该cȝgetScreenSize可以得到屏幕大小(英寸)QloadSystemColors可以列出所有的p? l颜艌Ӏ?/p>