前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA同步锁 synchronized(this)、synchronized(class)与synchronized(Object)的区别

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

作者头像
鳄鱼儿
发布2024-05-21 15:51:11
520
发布2024-05-21 15:51:11
举报
代码语言:javascript
复制
/**
 * 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)同步代码块

代码语言:javascript
复制
/**
 * 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方法

代码语言:javascript
复制
/**
 * 静态同步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)代码块

代码语言:javascript
复制
/**
 * 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锁对类的所有对象实例起作用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • synchronized同步方法和synchronized(this)同步代码块
  • 静态同步synchronized方法
  • synchronized(*.class)代码块
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档