Synchronized关键字加在方法上和类上的区别
Synchronized的作用及其用法
Synchronized关键字用于实现多线程的同步,确保在多个线程中访问共享资源时的正确性和一致性。
Synchronized关键字可以用于控制多线程对共享资源的访问,它有两种用法:一种是将其加在方法上,另一种是将其加在代码块上。
方法级别的同步(Synchronized methods)
当一个方法被声明为"synchronized"时,它被称为同步方法。同步方法可以确保同一时间只有一个线程可以执行该方法的代码块。
它会锁定整个对象,即锁住调用该方法的对象。也就是说,该方法只能在一个线程执行完之后,其他线程才能继续执行该方法或该对象的其他synchronized方法。
在这种情况下,锁定的范围是对象级别的。因此,如果在多个线程之间共享一个对象时,可能会发生竞争条件。
public synchronized void synchronizedMethod(){
// 同步代码块
// ...
}
在上面的示例中,当一个线程进入synchronizedMethod方法时,其他线程必须等待。
类级别的同步(Synchronized blocks on class)
当synchronized关键字被应用于一个类时,它会锁定整个类,即锁住该类的所有实例。
它会锁住的是类的级别,即类的静态成员和静态代码块。
这意味着只有一个线程可以同时执行类级别的同步代码块,无论是访问类的静态成员还是执行静态代码块。
也就是说,当一个线程获取该类的锁后,其他线程将不能访问该类的任何synchronized方法或代码块。这种方式比较少见,因为它可能会对程序性能产生一定的影响,而且它只能保证同一时刻只有一个线程访问该类的所有synchronized方法或代码块。
public class MyClass{
private static final Object lock = new Object();
public static void synchronizedMethod(){
synchronized(MyClass.class){
// 静态同步代码块
// ...
}
}
}
在上述示例中,我们使用MyClass.class作为锁来同步类级别的代码块。只有一个线程可以获取到这个锁,执行静态同步代码块,而其他线程则需要等待。
需要注意的是,类级别的同步锁是与类本身相关联的。因此,不同的类实例之间的同步代码块不会相互阻塞,因为它们具有不同的锁。只有同一个类的不同实例之间的类级别同步才会相互影响。
总之,当在类级别使用"synchronized"关键字时,它会锁住类的静态成员和静态代码块,确保在多线程环境中对这些资源的访问是线程安全的。
两种的区别
综上所述,synchornized关键字加在方法上和类上的主要区别在于锁定的粒度不同。加在方法上锁定的是调用该方法的对象,而加在类上锁定的是该类的所有实例,因此应根据具体的场景和需求来选择使用哪种方式。