Synchronized 的几种用法

1、同步普通方法

这个也是我们用得最多的,只要涉及线程安全,上来就给方法来个同步锁。这种方法使用虽然最简单,但是只能作用在单例上面,如果不是单例,同步方法锁将失效。

/**
 * 用在普通方法
 */
private synchronized void synchronizedMethod() {
    System.out.println("synchronizedMethod");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

此时,同一个实例只有一个线程能获取锁进入这个方法。

2、同步静态方法

同步静态方法,不管你有多少个类实例,同时只有一个线程能获取锁进入这个方法。

/**
 * 用在静态方法
 */
private synchronized static void synchronizedStaticMethod() {
    System.out.println("synchronizedStaticMethod");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

同步静态方法是类级别的锁,一旦任何一个线程进入这个方法,其他所有线程将无法访问这个类的任何同步类锁的方法。

3、同步类

下面提供了两种同步类的方法,锁住效果和同步静态方法一样,都是类级别的锁,同时只有一个线程能访问带有同步类锁的方法。

/**
 * 用在类
 */
private void synchronizedClass() {
    synchronized (TestSynchronized.class) {
        System.out.println("synchronizedClass");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 用在类
 */
private void synchronizedGetClass() {
    synchronized (this.getClass()) {
        System.out.println("synchronizedGetClass");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

这里的两种用法是同步块的用法,这里表示只有获取到这个类锁才能进入这个代码块。

4、同步this实例

这也是同步块的用法,表示锁住整个当前对象实例,只有获取到这个实例的锁才能进入这个方法。

/**
 * 用在this
 */
private void synchronizedThis() {
    synchronized (this) {
        System.out.println("synchronizedThis");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

用法和同步普通方法锁一样,都是锁住整个当前实例。

5、同步对象实例

这也是同步块的用法,和上面的锁住当前实例一样,这里表示锁住整个 LOCK 对象实例,只有获取到这个 LOCK 实例的锁才能进入这个方法。

/**
 * 用在对象
 */
private void synchronizedInstance() {
    synchronized (LOCK) {
        System.out.println("synchronizedInstance");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

另外,类锁与实例锁不相互阻塞,但相同的类锁,相同的当前实例锁,相同的对象锁会相互阻塞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
synchronized是Java中的一个关键字,用于实现线程的同步。它可以用于方法或代码块,并且只能修饰非静态方法、静态方法和代码块。 使用synchronized关键字可以解决多线程并发访问共享资源时可能出现的数据不一致或冲突的问题。当某个方法或代码块被synchronized修饰时,同一时间只能有一个线程执行该方法或代码块,其他线程需要等待。 synchronized使用方式有以下几种: 1. 修饰实例方法:使用synchronized修饰实例方法时,同一时间只有一个线程可以访问该实例的该方法。其他线程需要等待锁释放后才能执行该方法。 ```java public synchronized void method() { // 线程安全的操作 } ``` 2. 修饰静态方法:使用synchronized修饰静态方法时,同一时间只有一个线程可以访问该类的该静态方法。其他线程需要等待锁释放后才能执行该方法。 ```java public static synchronized void method() { // 线程安全的操作 } ``` 3. 修饰代码块:使用synchronized修饰代码块时,需要指定一个对象作为锁。同一时间只有一个线程可以获取该对象的锁,其他线程需要等待锁释放后才能执行代码块。 ```java public void method() { synchronized (lockObject) { // 线程安全的操作 } } ``` 使用synchronized关键字可以保证线程安全,但也会带来一些性能上的损耗。因为每个线程在执行synchronized方法或代码块时都需要先获取锁,如果锁被其他线程占用,线程就会进入等待状态,这会导致线程切换和上下文切换的开销。 另外,synchronized只能实现互斥同步,即同一时间只有一个线程能够执行被synchronized修饰的代码,无法实现并发访问。如果需要更高级的同步机制,可以考虑使用Lock接口和Condition接口提供的更灵活的锁定机制。 相关问题: 1. synchronized是如何实现线程同步的? 2. synchronized修饰静态方法和实例方法有什么区别? 3. synchronized代码块中的锁对象可以是任意对象吗?为什么? 4. 除了使用synchronized,还有哪些实现线程同步的方式?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值