Java并发编程(四)—synchronized关键字的应用

目录

1、synchronized适用场景

2、synchronized的原理

3、synchronized的锁升级

4、synchronized的注意事项

5、总结


synchronized 是 Java 中用于实现线程同步的关键字。它可以在方法级别或代码块级别使用,以确保同一时刻只有一个线程可以访问被同步的代码段。synchronized 通过内部锁机制来实现线程间的互斥访问

synchronized 关键字可以在方法级和代码块级使用:

①可以将 synchronized 用在方法级别上,这种情况下锁定的对象是当前对象(this)

public class MyClass {

    public synchronized void myMethod() {
        // synchronized 代码
    }

}

②也可以将 synchronized 关键字用在代码块级别上,这种情况下锁定的对象可以是当前对象(this),也可以是任意一个对象 

public class MyClass {

    private final Object lock = new Object(); // 定义一个对象作为锁

    public void myMethod() {
        synchronized (lock) {
            // synchronized 代码
        }
    }

}

🌰:多线程访问以下这段代码时,count结果会是多少呢?

public class SynchronizedTest implements Runnable{

    public static int count = 0;

    @Override
    public void run() {
        addCount();
    }

    public void addCount(){
        int i = 0;
        while (i++ < 1000) {
            count++;
        }
    }

    public static void main(String[] args) throws Exception{
        SynchronizedTest obj = new SynchronizedTest();
        Thread t1 = new Thread(obj);
        Thread t2 = new Thread(obj);
        t1.start();
        t2.start();
        t1.join(); // 等待 t1 线程执行完毕
        t2.join(); // 等待 t2 线程执行完毕
        System.out.println(count); // 打印 count 的值
    }
}

逻辑很简单, 最终的count值一定是<2000,由于t1线程获取count的值为0,然后执行了+1操作,但还未同步至主内存,此时,t2获取主内存中count=0,然后也执行了+1操作,那最终的结果依然是count=1

为了保证count的值=2000,就需要用到synchronized关键字

1、synchronized适用场景

  • 多线程环境下需要保证代码块或方法的原子性

当需要确保一段代码在多线程环境中只被一个线程执行时,可以使用 synchronized。

  • 保证多个变量之间的一致性:

当需要保证多个变量之间的操作是一致的时候,可以使用 synchronized 来确保这些操作作为一个整体被执行。

  • 防止死锁:

虽然 synchronized 可能会导致死锁,但也可以通过合理的锁顺序和锁粒度设计来预防死锁。

  • 保证可见性和有序性:

synchronized 关键字还可以保证可见性和有序性,确保线程间的数据同步

上面都是一些很空泛的概念,有木有,因此还是需要结合🌰来深入了解synchronized

掌声欢迎👏👏👏,🌰登场!

在上文中Java并发—CAS的原理及应用场景-优快云博客讲了利用CAS来实现抢票功能,没看过上文,也没关系,有兴趣可以看看,哈哈哈……

CAS操作多个变量时,会比较复杂,虽然保证多变量的一致性更新,但可能需要多次 CAS 操作和自旋重试,可能会消耗更多的 CPU 资源,那如果使用synchronized关键字实现上述功能呢


还是以之前的案例🌰:假设线程A和线程B,都在尝试购买不同活动的门票

public class Ticket {
    private int remainingTickets = 100; // 剩余票数
    private int eventId = 1; // 活动 ID

    public synchronized void buyTicket(int ticketsToBuy, int eventId) {
        if (remainingTickets >= ticketsToBuy) {
            this.eventId = eventId; // 更新活动 ID
            System.out.println(Thread.currentThread().getName() + " 成功购买 " + ticketsToBuy + " 张票");
            re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值