JAVA同步锁 synchronized(this)、synchronized(class)与synchronized(Object)的区别

/**
 * synchronized(this) 只能锁当前对象
 * synchronized(A.class) 锁类,对类的所有实例生效
 */

public class Synchronized {
    public void method1() { // 锁当前对象
        try {
            synchronized (this) {
                System.out.println("this   method1 start time=" + System.currentTimeMillis());
                Thread.sleep(2000);
                System.out.println("this   method1 end time=" + System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public synchronized void method2() { // 与method1存在竞争关系
        System.out.println("       method2 start time=" + System.currentTimeMillis());
        System.out.println("       method2 end time=" + System.currentTimeMillis());
    }

    public void method3() { // 锁类,对类的所有实例生效
        synchronized (Synchronized.class) {
            try {
                System.out.println("class  method3 start time=" + System.currentTimeMillis());
                Thread.sleep(4000);
                System.out.println("class  method3 end time=" + System.currentTimeMillis());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static synchronized void method4() { // 与method3存在竞争关系
        System.out.println("static method4 start time=" + System.currentTimeMillis());
        System.out.println("static method4 end time=" + System.currentTimeMillis());
    }

}

class Thread1 extends Thread {
    private Synchronized objectService;

    public Thread1(Synchronized objectService) {
        super();
        this.objectService = objectService;
    }

    @Override
    public void run() {
        super.run();
        objectService.method1();
    }
}

class Thread2 extends Thread {
    private Synchronized objectService;

    public Thread2(Synchronized objectService) {
        super();
        this.objectService = objectService;
    }

    @Override
    public void run() {
        super.run();
        objectService.method2();
    }
}

class Thread3 extends Thread {
    private Synchronized objectService;

    public Thread3(Synchronized objectService) {
        super();
        this.objectService = objectService;
    }

    @Override
    public void run() {
        super.run();
        objectService.method3();
    }
}

class Thread4 extends Thread {
    private Synchronized objectService;

    public Thread4(Synchronized objectService) {
        super();
        this.objectService = objectService;
    }

    @Override
    public void run() {
        super.run();
        objectService.method4();
    }
}

class MainTest {
    public static void main(String[] args) {
        Synchronized service = new Synchronized();

        new Thread1(service).start();
        new Thread2(service).start();
        new Thread3(service).start();
        new Thread4(service).start();
    }
}

输出结果:

在这里插入图片描述
从时间线可以看出method1method2method3method4存在竞争关系。
当一个线程访问Synchronized类的一个synchronized (this)同步代码块时,其它线程对同一个Synchronized类中其它的synchronized ()同步方法的访问将是堵塞;访问synchronized (Synchronized.class)同步代码块时, static synchronized同步方法的访问将是阻塞,这说明synchronized (this)和synchronized ()同步方法、synchronized (Synchronized.class)同步代码块和 static synchronized同步方法使用的对象监视器是一个。

synchronized同步方法和synchronized(this)同步代码块

/**
 * synchronized(this)锁定当前对象
 */

public class SynchronizedThis {
    public void methodA() {
        try {
            synchronized (this) {
                System.out.println("this methodA 线程名称:" + Thread.currentThread().getName() + " begin time=" + System.currentTimeMillis());
                for (int i = 1; i <= 2; i++) {
                    System.out.println("this methodA 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
                    Thread.sleep(100);
                }
                System.out.println("this methodA 线程名称:" + Thread.currentThread().getName() + " end  time=" + System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void methodB() {
        synchronized (this) {
            try {
                System.out.println("this methodB 线程名称:" + Thread.currentThread().getName() + " begin time=" + System.currentTimeMillis());
                for (int i = 1; i <= 2; i++) {
                    System.out.println("this methodB 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
                    Thread.sleep(100);
                }
                System.out.println("this methodB 线程名称:" + Thread.currentThread().getName() + " end  time=" + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void methodC() {
        try {
            System.out.println("     methodC 线程名称:" + Thread.currentThread().getName() + " begin time=" + System.currentTimeMillis());
            for (int i = 1; i <= 2; i++) {
                System.out.println("     methodC 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
                Thread.sleep(100);
            }
            System.out.println("     methodC 线程名称:" + Thread.currentThread().getName() + " end  time=" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class ThisThreadA extends Thread {
    private SynchronizedThis synchronizedThis;

    public ThisThreadA(SynchronizedThis synchronizedThis) {
        super();
        this.synchronizedThis = synchronizedThis;
    }

    @Override
    public void run() {
        super.run();
        synchronizedThis.methodA();
    }
}

class ThisThreadB extends Thread {
    private SynchronizedThis synchronizedThis;

    public ThisThreadB(SynchronizedThis synchronizedThis) {
        super();
        this.synchronizedThis = synchronizedThis;
    }

    @Override
    public void run() {
        super.run();
        synchronizedThis.methodB();
    }
}

class ThisThreadC extends Thread {
    private SynchronizedThis synchronizedThis;

    public ThisThreadC(SynchronizedThis synchronizedThis) {
        super();
        this.synchronizedThis = synchronizedThis;
    }

    @Override
    public void run() {
        super.run();
        synchronizedThis.methodC();
    }
}

class ThisMainTest {
    public static void main(String[] args) {
        SynchronizedThis service = new SynchronizedThis();
        ThisThreadA a = new ThisThreadA(service);
        a.setName("ThreadA");
        a.start();
        ThisThreadB b = new ThisThreadB(service);
        b.setName("ThreadB");
        b.start();
        ThisThreadC c = new ThisThreadC(service);
        c.setName("ThreadC");
        c.start();
    }
}

输出结果
在这里插入图片描述

多个线程调用同一个对象中的不同名称的synchronized同步方法或synchronized(this)同步代码块时,是同步的。

synchronized同步方法synchronized(this)同步代码块是相互竞争关系

  1. 对其它的synchronized同步方法或synchronized(this)同步代码块调用是堵塞状态;
  2. 同一时间只有一个线程执行synchronized同步方法或synchronized(this)同步代码块中的代码。

静态同步synchronized方法

/**
 * 静态同步synchronized方法
 * synchronized应用在static方法上,那是对当前对应的*.Class进行持锁。
 */
public class SynchronizedStatic {
    public synchronized static void methodA() {
        try {
            System.out.println("static methodA 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
            for (int i = 1; i <= 5; i++) {
                System.out.println("static methodA 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
                Thread.sleep(1000);
            }
            System.out.println("static methodA 线程名称:" + Thread.currentThread().getName() + " end   times:" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized static void methodB() {
        System.out.println("static methodB 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
        System.out.println("static methodB 线程名称:" + Thread.currentThread().getName() + " end   times:" + System.currentTimeMillis());
    }
}

class StaticThreadA extends Thread {
    @Override
    public void run() {
        SynchronizedStatic.methodA();
    }
}

class StaticThreadB extends Thread {
    @Override
    public void run() {
        SynchronizedStatic.methodB();
    }
}

class StaticMainTest {
    public static void main(String[] args) {
        StaticThreadA a = new StaticThreadA();
        a.setName("ThreadA");
        a.start();
        StaticThreadB b = new StaticThreadB();
        b.setName("ThreadB");
        b.start();
    }
}

输出结果
在这里插入图片描述
synchronized应用在static方法上,那是对当前对应的*.Class进行持锁,与同步synchronized(*.class)代码块作用一样。
对比下面代码进行验证

synchronized(*.class)代码块

/**
 * synchronized(*.class)代码块
 * 同步synchronized(*.class)代码块的作用其实和synchronized static方法作用一样。
 * Class锁对类的所有对象实例起作用。
 */
public class SynchronizedClass {
    public void methodA() {
        try {
            synchronized (SynchronizedClass.class) {
                System.out.println("class methodA 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
                for (int i = 1; i <= 5; i++) {
                    System.out.println("class methodA 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
                    Thread.sleep(1000);
                }
                System.out.println("class methodA 线程名称:" + Thread.currentThread().getName() + " end   times:" + System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void methodB() {
        synchronized (SynchronizedClass.class) {
            System.out.println("class methodB 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
            System.out.println("class methodB 线程名称:" + Thread.currentThread().getName() + " end   times:" + System.currentTimeMillis());
        }
    }
}

class ClassThreadA extends Thread {
    private SynchronizedClass objectService;

    public ClassThreadA(SynchronizedClass objectService) {
        super();
        this.objectService = objectService;
    }

    @Override
    public void run() {
        objectService.methodA();
    }
}

class ClassThreadB extends Thread {
    private SynchronizedClass objectService;

    public ClassThreadB(SynchronizedClass objectService) {
        super();
        this.objectService = objectService;
    }

    @Override
    public void run() {
        objectService.methodB();
    }
}

class ClassMainTest {
    public static void main(String[] args) {
        SynchronizedClass service = new SynchronizedClass();
        ClassThreadA a = new ClassThreadA(service);
        a.setName("ThreadA");
        a.start();
        ClassThreadB b = new ClassThreadB(service);
        b.setName("ThreadB");
        b.start();
    }
}

// Class锁对类的所有对象实例起作用。
class ClassMainTest2 {
    public static void main(String[] args) {
        SynchronizedClass service1 = new SynchronizedClass();
        SynchronizedClass service2 = new SynchronizedClass();
        ClassThreadA a = new ClassThreadA(service1);
        a.setName("ThreadA-service1");
        a.start();
        ClassThreadB b = new ClassThreadB(service2);
        b.setName("ThreadB-service2");
        b.start();
    }
}

输出结果
在这里插入图片描述

同步synchronized(*.class)代码块的作用其实和synchronized static方法作用一样。
Class锁对类的所有对象实例起作用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鳄鱼儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值