Java

基于Maven编写命令行应用:最佳实践

java命令行应用 = 一些*.jar文件   +  *.sh可执行脚本 如果你的应用是基于maven的, 可以参考以下实践,避免走弯路。 以下所有资料从网上汇集而来 使用assembly插件将jar和可执行脚本打包成 *.zip <!–pom.xml–> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.3</version> <configuration> <descriptors> <descriptor>src/main/assembly/assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <!–src/main/assembly/assembly.xml –> <!–jar文件将打在zipFile/jars目录下 –> <!–脚本文件可以src/main/bin下,打包后在zipFile/bin目录下–> <assembly> <id>jarset</id> <formats> <format>zip</format> </formats> <includeBaseDirectory>true</includeBaseDirectory> <fileSets> <fileSet> <directory>src/main/bin</directory> <outputDirectory>/bin</outputDirectory> <fileMode>755</fileMode> <directoryMode>755</directoryMode> </fileSet> </fileSets> <dependencySets> <dependencySet> <outputDirectory>/jars</outputDirectory> <scope>runtime</scope> </dependencySet> </dependencySets> …

基于Maven编写命令行应用:最佳实践 Read More »

Maven: dependency tree应在assembly工程下进行

一个用Maven管理的应用可能会有多个子工程,比如app + web + common等。 如果你要分析depenency, 比如要找出哪些jar将被omit, 你应该在assembly这个子工程下(比如web)做。 否则,如果你在总工程下做分析,会发现很多该omitted的entry没有被omit. 具体就不解释了。

synchronized锁机制详解

synchronized关键字用在方法签名上或者代码块上,用于给资源加锁。不过这个锁的粒度并不限于这个方法或者代码块。它是“对象级别的锁”。 这个所谓的“对象级别的锁”那底是什么意思呢? 也就是说,当一个线程持有这个锁时,访问同一个对象的另一个线程倒底会受到什么影响? 经实验,结论如下: 1. 当一个线程在执行一个synchronized方法时,另一个线程无法立即执行同一个对象的相同方法,也不能执行这个对象的其他任意一个synchronized方法。这就是“对象级别锁”的意义。 2. 当一个线程在执行一个synchronized方法时,另一个线程可以立即执行同一个对象的任意一个非synchronized方法 3. 当一个线程在执行一个synchronized代码块时,另一个线程无法立即执行同一个对象的任意一个synchronized方法,但可以立即执行同一个对象的任意一个非synchronized方法 4. 当一个线程在执行一个synchronized代码块时,另一个线程无法立即执行施加在同一个对象的任意一个synchronized代码块 5. 当一个线程在执行一个synchronized代码块时,另一个线程可以立即执行施加在同一个对象的任意一个非synchronized代码块,即使后者与前者调用了相同的方法 可以看出,synchronized代码块和synchronized方法基本上是对等的。那么,当一个线程在执行一个synchronized方法时,另一个线程是否能够立即执行施加在同一个对象的一个syncrhonized代码块? 答案是显然的。 总之,在同一个对象内,synchronized和非synchronized的资源不会彼此阻塞访问,只有synchronized和synchronized的资源会互相阻塞访问

java线程池的maxSize应该设多大?

今天听高人透露了一个公式: 引用 maxSize =  逻辑cpu数/(1 – I/O等待时间占比) 也就是说, 1. 如果你的任务是纯CPU操作,则maxSize = cpu数,一个CPU服务一个线程。如果线程数<cpu数,则cpu的并行能力未得到充分利用;如果线程数>cpu数,吞吐率也不会变高,反而会因为过多context switch而损害性能。 2. 如果你的任务I/O等待占了一半时间,则maxSize = cpu * 2; 这时,用于cpu操作的线程数是maxSize的一半,恰好=cpu数。如果你的cpu是双核,则maxSize=4, 当4个中的2个线程因为I/O而阻塞时,另外两个非I/O线程可以被调度进来,刚好占满CPU的坑位。

推荐一个GC日志分析工具: PrintGCStats

一个用shell写成的GC日志分析工具,用于进行各种统计,非常小巧好用。 下载: 点这里 使用: ./PrintGCStats -v cpus=4 ~/temp/gc.log #cpus代表逻辑cpu数 样例输出: 引用 what           count          total          mean           max     stddev gen0(s)            4         15.606       3.90150        11.344     5.0888 gen0t(s)           4         15.607       3.90169        11.344     5.0888 cmsIM(s)         225        740.826       3.29256         3.908     0.3529 cmsRM(s)         224        654.354       2.92122         3.570     0.3063 GC(s)            229       1410.787       6.16064        11.344    -1.0000 cmsCM(s)         224        960.213       4.28667         6.262     0.1990 cmsCP(s)         448       …

推荐一个GC日志分析工具: PrintGCStats Read More »

找出线上java应用中的哪段代码在大量耗费性能

你发现你的机器的cpu usage达到了100%,并且发现都是你的java应用导致的;但是,这个应用里具体哪段代码在这样吃性能呢? 以下来自一个同事的分享: 1. 先找出吃性能的线程: top -H -p pid,找出最耗性能的线程ID(最左列) 2. 获得线程ID的16进制表示: printf ‘0x%x\n’ 线程ID 3. 然后生成一下jstack,比如 kill -3 pid 4. 在生成的jstack里搜索 线程ID的16进制表示即可

@Autowired优先按type注入,@Resource优先按name注入

在spring框架下使用注入annotation,应该用@Autowired还是@Resource? 基本上都差不多,但如果存在不同bean共享同一个java类的情况,则应该使用@Resource. 因为, @Resource寻找bean的顺序   Matches by Name   Matches by Type @Autowired寻找bean的顺序    Matches by Type      //如果存在不同Bean共享java类,就会出现NoUniqueBean异常   Matches by Name 更多请见 http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/

正则表达式里可以使用括号来标识一个子串以供后用

正则表达式里可以使用括号来标识一个子串以供后用 比如 要识别所有 "Hello,xxx yyy"串并将Hello替换为Goodbye, 可以这样   Hello\,([a-zA-Z]+)\s([a-zA-Z]+) 然后在替换时使用表达式   Goodbye,$1,$2 $1和$2分别代表正则式里的第一、第二个括号里的子串