【Java】Java线程的同步机制-synchronized【主线学习笔记】


前言

Java是一门功能强大且广泛应用的编程语言,具有跨平台性和高效的执行速度,广受开发者喜爱。在接下来的学习过程中,我将记录学习过程中的基础语法、框架和实践技巧等,分享学习心得,对自己学习过程进行整理和总结,也希望能为其他学习Java的朋友提供一些帮助和参考。


在Java中,为了解决多线程并发导致的数据安全问题,通常使用同步机制来确保线程安全。以下是对线程同步机制的整理:

Java线程的同步机制

Java通过synchronized关键字提供了两种同步机制来解决线程安全问题:

1. 同步代码块

synchronized(同步监视器) {
    // 需要被同步的代码
}
  • 同步代码:被synchronized包裹的代码。主要用于操作共享数据(即多个线程需要操作的数据,例如票数ticket)。
  • 同步监视器:俗称“锁”,用来控制访问共享资源。哪个线程获取了同步监视器锁,哪个线程就可以执行同步代码,其他线程必须等待。必须是唯一的
  • 注意:多个线程必须共用同一个同步监视器对象才能保证同步。

示例:

public class WindowTest {
    public static void main(String[] args) {
        Ticket t = new Ticket();
        // 创建三个窗口(线程)
        Thread window1 = new Thread(t);
        Thread window2 = new Thread(t);
        Thread window3 = new Thread(t);
        window1.setName("窗口1");
        window2.setName("窗口2");
        window3.setName("窗口3");
        // 启动线程

        window1.start();
        window2.start();
        window3.start();


    }
}

class Ticket implements Runnable {
    private int ticketNum = 100;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {  // 加同步锁,确保线程安全,此时在主线程中Ticket只被实例化一次,因此this是唯一的
                if (ticketNum > 0) {
                    // 模拟售票过程
                    System.out.println(Thread.currentThread().getName() + " 售出一张票,剩余票数:" + (ticketNum - 1));
                    ticketNum--;  // 售出一张票
                } else {
                    break;  // 票卖完了,退出
                }
            }
            // 模拟售票窗口间的时间差
            try {
                Thread.sleep(50); // 休眠50毫秒,模拟真实售票场景
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

2. 同步方法

除了同步代码块,还可以将需要同步的代码封装在方法内,并在 方法上直接加上synchronized修饰符,使整个方法成为同步方法。

public synchronized void sellTicket() {
    // 需要被同步的代码
}
  • 同步方法:无需显式指定同步监视器,默认同步监视器是当前对象(this),若为静态方法,则是当前类本身(类名.class)。
  • 优点:同步方法可以简化代码结构,避免手动添加synchronized块。

示例:

class TicketSale implements Runnable {
    private int ticket = 100;

    @Override
    public void run() {
        while (ticket > 0) {
            sellTicket();
        }
    }

    private synchronized void sellTicket() {
        if (ticket > 0) {
            System.out.println(Thread.currentThread().getName() + " 卖出第 " + ticket-- + " 张票");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

虫本初阳

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

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

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

打赏作者

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

抵扣说明:

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

余额充值