synchronized(this)、synchronized(.class)、锁静态方法、方法区别?

简介: synchronized(this)、synchronized(.class)、锁静态方法、方法区别?

一、synchronized 与 synchronized static区别?


synchronized:对像的当前实例进行加锁,防止其他线程同时访问该类实例的所有synchronized块。

synchronized static:是限制线程同时访问jvm中该类的所有实例同时访问对应的代码块,且该类的所有代码块共用一把锁。

pulbic class syncMethod(){
       public synchronized void syncA(){}
       public synchronized void syncB(){}
       public static synchronized void staticA(){}
       public static synchronized void staticB(){}
}

假设上面的类有四个方法,然后有两个实例a,b调用,那么哪些可以同时被访问呢?

1、a.syncA()  和 a.syncB()。

2、a.syncA()  和 b.syncB()。

3、a.staticA() 和 b.staticB()。

4、a.staticA() 和 syncMethod.staticB()。

这里我们可以根据上面两个定律判断:

1、这个肯定是可以加锁成功,两个线程不能同时访问。

2、这个肯定加锁失败,两个线程可以同时访问。

3、这个因为是静态,而且是不同的实例,根据定律也是可以加锁成功,两个线程不能同时访问。

4、这里因为一个是实例方法锁,一个是类方法锁,锁的对象不同,所以可以被同时访问。


二、synchornized(this)和synchronized(.class)


对象锁只对当前对象进行加锁,锁this和synchronized普通方法一样,只对调用的实例进行加锁,而锁.class是指对类加锁。


synchornized(this)

public class Sync823 {
    public static void main(String[] args) {
        Service823 service823 = new Service823();
        ThreadA823 threadA823 = new ThreadA823(service823);
        threadA823.setName("鸣人");
        threadA823.start();
        Service823 service82311 = new Service823();
        ThreadB823 threadB823 = new ThreadB823(service823);
        threadB823.setName("佐助");
        threadB823.start();
    }
}
class Service823{
    void thread823(){
        synchronized (this){
            for (int i = 0; i < 100; i++) {
                if(Thread.currentThread().getName().equals("鸣人")){
                    System.out.println("鸣人释放 螺旋丸");
                    continue;
                }
                System.out.println("佐助释放 千鸟");
            }
        }
    }
}
class ThreadA823 extends Thread{
    private Service823 service823;
    ThreadA823(Service823 service823){
        this.service823 = service823;
    }
    @Override
    public void run() {
        service823.thread823();
    }
}
class ThreadB823 extends Thread{
    private Service823 service823;
    ThreadB823(Service823 service823){
        this.service823 = service823;
    }
    @Override
    public void run() {
        service823.thread823();
    }
}
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟

从上面代码可以看到,当锁this的时候,当是同一个实例,这时候是上锁成功,两个线程不会同时访问,和前面的synchronized修饰普通方法一样,但如果换成 不同的实例,则不会互斥。

public static void main(String[] args) {
        Service823 service823 = new Service823();
        ThreadA823 threadA823 = new ThreadA823(service823);
        threadA823.setName("鸣人");
        threadA823.start();
        Service823 service82311 = new Service823();
        ThreadB823 threadB823 = new ThreadB823(service82311);
        threadB823.setName("佐助");
        threadB823.start();
    }
佐助释放 千鸟
佐助释放 千鸟
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
佐助释放 千鸟
佐助释放 千鸟

synchronized(.class)

 synchronized (Service823.class){
            for (int i = 0; i < 100; i++) {
                if(Thread.currentThread().getName().equals("鸣人")){
                    System.out.println("鸣人释放 螺旋丸");
                    continue;
                }
                System.out.println("佐助释放 千鸟");
            }
        }
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟


这时候会发现,无论是创建几个实例,都会互斥成功,所以锁.class锁的是这个类,并不是实例。


相关文章
|
2月前
|
安全 Java
synchronized修饰普通方法和静态方法的区别
在Java多线程中,`synchronized`关键字用于同步机制,确保线程安全。修饰普通方法时,同步基于对象实例,仅同步访问同一对象的方法调用,不同对象间互不影响。修饰静态方法时,则基于类级别,所有对象访问同一静态方法时会互相阻塞。前者适合保护对象状态,后者适用于类级资源同步。需注意,修饰静态方法可能会影响并发性能。实际应用中应根据需求选择适当的同步策略,以平衡程序正确性和效率。
|
5月前
|
存储 安全
除了Lock对象,还有其他方法可以实现多线程安全的单例模式吗?
【2月更文挑战第5天】【2月更文挑战第12篇】除了Lock对象,还有其他方法可以实现多线程安全的单例模式吗?
28 1
|
12月前
|
安全 算法 Java
synchronized 同步锁
Java中的synchronized关键字用于实现线程同步,可以修饰方法或代码块。 1. 修饰方法:当一个方法被synchronized修饰时,只有获得该方法的锁的线程才能执行该方法。其他线程需要等待锁的释放才能执行该方法。 2. 修饰代码块:当某个对象被synchronized修饰时,任何线程在执行该对象中被synchronized修饰的代码块时,必须先获得该对象的锁。其他线程需要等待锁的释放才能执行同步代码块。Java中的每个对象都有一个内置锁,当一个对象被synchronized修饰时,它的内置锁就起作用了。只有获得该锁的线程才能访问被synchronized修饰的代码段。使用synch
57 0
|
安全 Java 调度
线程安全——Synchronized
线程安全——Synchronized
66 0
synchronized(this)、synchronized(class)和synchronized(Object)的区别
synchronized(this)、synchronized(class)和synchronized(Object)的区别
92 0
synchronized(this)、synchronized(class)和synchronized(Object)的区别
|
前端开发 Java Spring
方法上加上 synchronized 就可以了么
方法上加上 synchronized 就可以了么
|
安全 Java Spring
Synchronized代码详解?
Synchronized代码详解?
|
Java
JAVA同步锁 synchronized(this)、synchronized(class)与synchronized(Object)的区别
利用实例介绍JAVA同步锁 synchronized(this)、synchronized(class)与synchronized(Object)的区别
135 0
JAVA同步锁 synchronized(this)、synchronized(class)与synchronized(Object)的区别
synchronized 加锁 this 和 class 的区别!(2)
synchronized 加锁 this 和 class 的区别!(2)
117 0
synchronized 加锁 this 和 class 的区别!(2)
synchronized 加锁 this 和 class 的区别!(4)
synchronized 加锁 this 和 class 的区别!(4)
90 0
synchronized 加锁 this 和 class 的区别!(4)