synchronized
参考:
http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html
http://blog.csdn.net/xiao__gui/article/details/8188833
进行同步之前首先想好要同步的是什么,选好是同步方法还是同步语句块,控制锁的粒度。
1、同步加锁的是对象,而不是代码。不同对象都执行下面方法都是能够成功的,但如果是同一个对象重复执行下面方法会阻塞。
1)同步方法:
public synchronized void test() {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
2)同步对象:这里同步的是当前自身对象,效果和同步方法相同
public void test() {
synchronized(this){
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
2、语句块的同步:类(比如使用class方法)的同步、公共对象比如static对象的同步 这两种方法相同??? 应该是相同的,本质都是对同一对象进行同步
本质上都是对对象加锁!!!
可以实现锁住同一段代码,也就是同一时刻,不同线程只能有一个执行该语句块。
1)类的同步
public void test() {
synchronized (Sync.class) {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
2)静态对象的同步
public void test() {
synchronized (“该类当中声明的静态对象”) {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
3、方法的同步
1)如果使用static synchronized同步方法,static方法可以直接类名加方法名调用,方法中无法使用this,所以它锁的不是this,而是类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。应用:同一时刻,多个对象多个线程只能有唯一线程唯一对象调用该方法。
2)如果一个对象有多个synchronized方法synchronized aMethod(){},只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法。原理在于,这里的synchronized针对的是当前自身对象。
4、如果synchronized针对的是相同的字符串,那么锁的是同一个对象 因为JVM有一种优化机制,因为String类型的对象是不可变的,因此当你使用""的形式引用字符串时,如果JVM发现内存已经有一个这样的对象,那么它就使用那个对象而不再生成一个新的String对象,这样是为了减小内存的使用。
参考:不可变对象 http://www.jb51.net/article/49092.htm
1).不可变对象可以提高String Pool的效率和安全性。
2).不可变对象对于多线程是安全的。
5、synchronized不继承,需要显式指定。
6、synchronized可作用于instance变量(得是一个对象)、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock= new Object()则需要7行操作码。