1、当存在父子类继承关系是,子类完全可以通过“可重入锁”调用父类的同步方法的。
2、同步不能继承,需要在子类的方法中添加synchronize关键字
synchronize同步方法、变量;锁定当前对象
// 异步调用service1()、service2()、service3()方法时,
// 会等待当前调用的方法完成后才调用下一个方法。
public static class Service {
synchronized private void service1() {
System.out.println("service1");
try {
Thread.sleep(3000);
System.out.println("service1 end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized private void service2() {
System.out.println("service2");
}
synchronized private void service3() {
System.out.println("service3");
}
}
synchronize(this)同步代码块,锁定当前对象
synchronize(非this对象x)同步代码块,锁定非this对象x
示例代码:
-----------------重点代码-----------------------
public static class Service {
private String anything = "";
private void service1() {
synchronized (anything) {
try {
System.out.println("service begin");
Thread.sleep(3000);
System.out.println("service end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized private void service2() {
System.out.println("service2");
}
}
-----------------重点代码-----------------------
public static class MyThread1 extends Thread {
private final Service service;
MyThread1(Service service) {
this.service = service;
}
@Override
public void run() {
super.run();
service.service1();
}
}
public static class MyThread2 extends Thread {
private final Service service;
MyThread2(Service service) {
this.service = service;
}
@Override
public void run() {
super.run();
service.service2();
}
}
public static void main(String args[]) {
try {
Service service = new Service();
MyThread1 myThread1 = new MyThread1(service);
myThread1.start();
MyThread2 myThread2 = new MyThread2(service);
myThread2.start();
} catch (Exception e) {
e.printStackTrace();
}
}
打印结果:
service begin
service2
...
service end
分析:
由于对象监视器不同,所以运行结果就是异步的。
同步代码块放在非同步synchronize方法中进行声明,并不能保证调用方法的线程的执行同步/顺序性,调用方法是无序的,虽然同步块中的执行顺序是同步的,极易出现“脏读”问题
Class锁:对类的所有对象实例起作用。synchronized static private void method()、synchronize(Service.class)
public static class Service {
public static void method() {
synchronized (Service.class) {
System.out.println("Service.class 类锁");
}
}
synchronized public static void method2(){
System.out.println("类锁");
}
}
总结:
public static class Service {
public void method1() {
synchronized (Service.class) {
// Service.class 类锁
}
}
synchronized public static void method2() {
// Service.class 类锁
}
public void method3() {
synchronized (this) {
// 对象锁,Service的实例对象
}
}
synchronized public void method4() {
// 对象锁,Service的实例对象
}
// 一般不使用String作为对象锁,因为常量值相等时是同一个对象
private final String anything = "";
public void method5() {
synchronized (new Object()) {
// String 对象锁
}
}
}
// 只要对象不变,即使对象的属性变化,运行结果还是同步的。