一、作用效果
使用该关键字修饰的方法,在同一时刻最多只有一个线程可以进入。如果第一个线程获取锁进入了synchronized修饰的方法,在其释放锁之前,需要进入该实例中synchronized修饰的方法或者代码段的其他线程就需要等待,直到第一个线程释放锁之后,其他线程中才会有一个线程接着获取锁,进入互斥资源访问区。
二、用synchronized锁定Instance
线程通过该方式得到的是实例对象锁,锁定的方法或者代码块为互斥访问区,只要有一个线程获得了实例对象锁,其他线程对该实例对象的互斥访问区的访问都将阻塞。这种情况下synchronized只锁定某个具体的对象,而对于该对象所属类的其他对象没有影响。分情况描述如下:
- 当两个并发线程访问同一个实例对象中的互斥访问区时,一个时间内只能有一个线程得到执行。 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
- 当一个线程访问实例对象的一个互斥访问区时,另一个线程仍然可以访问该实例对象中的非互斥访问区代码块。
- 当一个线程访问实例对象的一个互斥访问区时,其他线程对实例对象中所有其它互斥访问区的访问将被阻塞。
- 当一个线程访问实例对象的一个互斥访问区时,它就获得了这个实例对象的对象锁。结果,其它线程对该实例对象所有同步代码部分的访问都被暂时阻塞。
三、synchronized锁定Instance的两种用法
这两种用法都是在实例对象上加锁,该实例对象包括该方法在内的任何synchronized修饰的方法,其他线程都不可进入,直到线程a释放锁,退出该方法。而该实例对象没有用synchronized修饰的方法,其他线程仍旧可以访问。
1.方法声明时使用
public synchronized void synMethod(){
//方法体
}
2.方法内使用
public void synMethod(){
synchronized(this){
//一次只能有一个线程进入
}
}
四、用synchronized锁定Class对象
线程通过该方式锁定的是当前对象的Class对象,与锁定Instance不同的是,线程a获取到Class对象的锁定之后,其他线程对该Class的所有对象实例互斥访问区的访问都将阻塞。
五、锁定Class对象的两种方法
1.静态方法声明时使用
public synchronized static void synMethod(){
//方法体
}
2.方法内使用
class A{
}
public void synMethod(){
synchronized(A.class){
//一次只能有一个线程进入
}
}