按月存档: 2012/07

Java中线程的创建

分类:java, 并发评论:7条作者:ticmy日期:2012-07-27

无论是网上还是一些书籍,包括Thread类的API文档中都写着创建线程有两种方式,一是extends Thread类,二是implements Runnable接口。然而,这种分类方式我很不喜欢,极易给一些人带来误解,让不少人以为implements Runnable接口就是创建了线程。 说“线程”在很多地方不容易分辨清楚,这里定义一个规则,下文说到“Java线程对象”的时候指的是java.lang.Thread类的一个对象,说到“可供CPU调度的线程”指的是一个真正可运行(或运行过)的线程。 先说说线程对象,在java.lang.Thread API中可以看到,目前其构造方法有8个,如下: public Thread() public Thread(Runnable target) public Thread(ThreadGroup group,Runnable target) public Thread(String name) public Thread(ThreadGroup group,String name) public Thread(Runnable target,String name) public Thread(ThreadGroup group,Runnable target,String name) public Thread(ThreadGroup group,Runnable target,String name,long stackSize) 创建一个Java线程对象目前有八种方式,可以传入很多参数以满足需求。实现了Runnable接口的类对象只是作为一个参…

Wait-Notify机制

分类:java, 基础, 并发评论:6条作者:ticmy日期:2012-07-21

Wait-Notify机制可以说是实现阻塞操作较为高效的一种方式。虽然在实际中鼓励使用类库中已有的满足条件的类,或基于类库中的类来做满足自己特殊需求的开发,并不建议直接使用如此底层的机制,但了解其原理还是很有必要的。 典型的Wait-Notify场景一般与以下内容相关: 1、状态变量(State Variable) 当线程需要wait的时候,总是因为一些状态不满足导致的。如往BlockingQueue里加元素队列已满的时候。当状态满足的时候,程序就可以执行下去。 2、条件断言(Condition Predicate) 当线程确定是否进入wait或者从notify中醒来的时候是否继续往下执行,大都要测试状态条件是否满足,如往BlockingQueue里加元素队列已满,于是阻塞,后续其它线程从队列里取走了元素,就通知在等待的线程“队列不是满的了,可以往里加东西了”,这时候在等待的线程就会醒来,然后看看是不是真的队列不为满的状态,如果是,就将元素添加进去,如果不是,就继续等待。 3、条件队列(Condition Queue) 每个对象都有一个内置的条件队列,当一个线程在该对象是调用wait的时候,就会将该线程加入该对象的条件队列。 基于以上,接下来说说wait(以及其它两个带超时时间的wait重载版本,后文…

Java反射详解

分类:java, 基础评论:12条作者:ticmy日期:2012-07-20

反射,是Java中非常重要的一个功能,如果没有反射,可以说很多框架都难以实现。 什么是反射?说白了就是可以通过Java代码获取装载到方法区的类信息的手段。 当装载一个类时,会在方法区产生一个数据结构,该结构中包含着装载的类的相关信息。字节码可以看成是数据流,那么方法区的这种数据结构可以说是字节码数据流的结构化表现。装载的最终产物就是java.lang.Class类的一个对象,它是Java程序与方法区内部数据结构之间的接口。 那么,我们能通过这个接口访问内部数据结构的哪些信息呢?接下来介绍关于反射常用的一些内容。反射的大部分方法大都与安全管理器有关,本文忽略此部分。 假设有以下代码(一个简单的文章管理代码) package com.ticmy.reflect; /** * 文章管理接口 * @author Administrator */ public interface ArticleInterface { public void del(long id) throws Exception; public void add(String content) throws Exception; public void modify(long id, String content) throws Exception; } 一个简单实现 package com.ticmy.reflect; import java.util.Map; import java.util.Random; import java.util.concur…
Tags: ,

内置锁与Lock

分类:java, 并发评论:4条作者:ticmy日期:2012-07-19

说到Java中的锁,大部分时候自然而然想到的还是内置锁,即synchronized方法或synchronized块;自jdk1.5开始,Java提供了Lock接口。那么Lock是否是内置锁的替代品,它们之间的区别和联系又有哪些呢? 内置锁与Lock之间的相同点: 1、相同的内存语义。两者都可以保证内存可见性,都可以实现互斥访问。 2、synchronized是可重入的,Lock也可以实现成可重入的,且绝大部分实现都是可重入的。所谓重入,就是一个线程获取一个锁后,还可以继续获取该锁。如两个使用了相同锁的实例方法间的调用。 它们间的不同点: 先看看Lock接口中与锁相关的方法声明: void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); 可以看出,Lock相比内置锁有更多可操作的地方,更加灵活。但同时灵活也意味着更容易出错。使用Lock,典型的代码结构如下: Lock lock = ... lock.lock(); try { //...do sth. } finally { lock.unlock(); } 锁定(包括lock、lockInterruptibly,两个重载的tryLock)与unlock总是成对出现的。目前类库…

equals和==

分类:java, 基础评论:5条作者:ticmy日期:2012-07-10

很多不明真相的javaer喜欢纠结于此问题,特来解释一二。 先看代码 StringBuilder s1 = new StringBuilder(); StringBuilder s2 = new StringBuilder(); String s = "abc"; s1.append(s); s2.append(s); System.out.println("s1.equals(s2):\t\t" + (s1.equals(s2))); System.out.println("s1 == s2:\t\t" + (s1 == s2)); String s3 = s + "1"; String s4 = s + "1"; System.out.println("s3 == s4:\t\t" + (s3 == s4)); System.out.println("s3.equals(s4):\t\t" + (s3.equals(s4))); Object obj1 = new Object(); Object obj2 = new Object(); System.out.println("obj1.equals(obj2):\t" + (obj1.equals(obj2))); System.out.println("obj1 == obj2:\t\t" + (obj1 == obj2)); 执行结果如下 s1.equals(s2): false s1 == s2: false s3 == s4: false s3.equals(s4): true obj1.equals(obj2): false obj1 == obj2: false 有人说“==比较地址,equals比较内容”,从String的比较来看这是对的,但从上述StringBuilder来…

32位jvm还是64位jvm?

分类:java评论:2条作者:ticmy日期:2012-07-07

在早期,JVM只有32位的,众所周知,32位有4G的内存限制。需要注意的是,32位jvm的堆内存实际可设的大小还受操作系统的限制。Hotspot VM,在Windows下,最大的堆内存大约在1.5G左右;在基于较新的linux kernel的Linux系统下,其限制在2.5到3G之间,在早前的linux kernel下,大约在2G左右;在Solaris下,为3.3G左右。 64位的hotspot VM允许使用更大的堆内存。 但是,64位JVM会有一些性能损失。主要在于普通对象指针(ordinary object pointers或oops)的size增大了,由32位增加到64位,这导致CPU cache中可用的oops减少,降低CPU缓存效率,相比32位,64位jvm的CPU缓存效率降低了8%到15%。 Java 6 HotSpot VM开始提供了一个压缩的普通对象指针的特性,可通过命令行参数-XX:+UseCompressedOops启用,这样就能受益于64位VM带来的内存,也不会有太大的性能损失。当然,压缩与解压缩oops仍然有性能的损耗。 更多阅读: 《Java Performance》by Charlie Hunt and Binu John,Chapter 3. https://wikis.oracle.com/display/HotSpotInternals/CompressedOops …
Tags: ,