1、synchronized修饰普通方法和静态方法的区别?什么是可见性?
对象锁是用于对象实例方法,或者一个对象实例上的, 类锁 是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,类锁其实锁的是每个类的对应的class对象。类锁和对象锁之间也是互不干扰的。
对象锁:
/**
* 对象锁 synchronized修饰普通方法 锁的是当前类实例对象
*/
public synchronized void syncMethod1() {
//do working...
}
复制代码
private final Object o = new Object();
/**
* 对象锁 锁的是Object对象实例
*/
public void syncMethod2() {
synchronized (o) {
//do working...
}
}
复制代码
类锁:
/**
* 类锁 synchronized修饰静态方法 锁的是当前类唯一的.class对象,也就是SynchronizedType.class,等同于下面的syncMethod3()
*/
public static synchronized void syncMethod3() {
//do working...
}
复制代码
/**
* 类锁 锁的是当前类唯一的.class对象。
*/
public void syncMethod4() {
synchronized (SynchronizedType.class) {
//do working...
}
}
复制代码
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
由于线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量,那么对于共享变量V,它们首先是在自己的工作内存,之后再同步到主内存。可是并不会及时的刷到主存中,而是会有一定时间差。很明显,这个时候线程A对变量V的操作对于线程B而言就不具备可见性了 。
要解决共享对象可见性这个问题,我们可以使用 volatile 关键字或者是加锁。