一。synchronized是保证线程安全的一种方法。它实现的功能有两种锁:
1.对象锁
(1)synchronized修饰成员方法
例如:
public synchronized void run(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这时候的锁是以当前方法所属的类的实例添加的。
(2)用synchronized修饰代码块,并用对象加锁
public void run(){
synchronized (this){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这时候的锁是以this对象为锁添加的,this对象也可以是开发人员new的其他对象。这里用this,那么所就是调用该方法的对象本身。
2.类锁
(1)synchronized修饰类成员方法
public static synchronized void run(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这时候的锁对象是该静态方法所在的类*.class对象。
(2)用synchronized修饰代码块,并用*.class加锁
public void run(){
synchronized (Test.class){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这时候的所对象是Test.class。这里说明一下,我这里用的是Test.class,这个可以替换成你想使用的任何*.class对象。
二。synchronized实现的同步功能的优缺点
1.可重入的
这个意思就是,当你持有synchronized锁,没有释放之前,你进入其他与该方法有相同锁的方法,是不需要释放当前锁并重新获取锁的。就比如递归,当前synchronized修饰的方法调用自己,是完全可以的。
2.不可中断的
当前持有锁的线程,不会被其他想要获取锁的线程打断。只有当前线程执行完释放锁,其他线程才可以获取该锁。
3.锁的持有和释放是JVM控制的,不需要自己维护。
当前线程获取锁和释放锁,开发人员不能随意用代码实现,只能代码执行中JVM根据monitor来加锁和释放锁。对synchronized没有像java的Lock接口提供提前释放锁的方法。