理解synchronized关键字
一、synchronized关键字的含义
Java中的synchronized关键字的作用是为了防止资源冲突。当某个任务要执行被synchronized关键字修饰的代码片段时,它将检查锁是否可用,然后获取锁,执行代码片段,最后释放锁。
synchronized关键字可以修饰普通方法、静态方法和代码块。而这三者之间对于锁对象的获取都是不太一样的。
二、synchronized关键字锁对象的差异
1、修饰普通方法
当synchronized关键字修饰普通方法时,见如下的例子:
public class Test {
public synchronized void test() {
xxx
}
}
上面的例子中使用了synchronized关键字修饰了类Test的普通方法test。由于test()方法是一个非静态方法,而非静态方法是属于某一个对象的,所以synchronized关键字锁住的是这个对象。当某一个线程执行该方法时,必须要先获取该对象的锁,否则需要等待。而当线程获取了该对象锁后,由于该锁锁住的是对象,所以该对象的其他非静态方法如果加上了synchronized关键字的,也是不能被其他线程所执行的。所以当多个线程不同对象访问该方法时,无法保证同步。
2、修饰静态方法
当synchronized关键字修饰静态方法时,见如下的例子:
public class Test {
public static synchronized void test() {
xxx
}
}
上面的例子中使用了synchronized关键字修饰了类Test的静态方法。由于静态方法是属于类Test的,所以synchronized关键字锁住的是该类对象。所以当多个线程不同对象访问该静态方法,也是可以保证同步的。
3、修饰代码块
当synchronized关键字修饰代码块时,见如下的例子:
public class Test {
public void test() {
synchronized(obj) {
Log.d("ABC", "111");
}
synchronized(Test.class) {
Log.d("ABC", "222");
}
}
}
上面的例子中使用了synchronized关键字修饰了两个代码块,其中synchronized(obj) ,这里的obj可以是类实例对象的一个属性,也可以是当前的实例对象,它的同步效果和synchronized关键字修饰普通方法是一样的,而synchronized(Test.class)锁住的是类对象,其同步效果和修饰静态方法的一样的。
4、总结
synchronized修饰方法时,控制的范围是比较大的,它会同步对象中所有synchronized方法的代码。而synchronized代码块控制的范围比较小,它只是同步同步代码块中的代码,而在代码块之外的是可以被多个线程访问的。