JUC基础-C2-synchronized&Lock接口

本文介绍了Java多线程编程中的Lock接口与synchronized关键字的使用,包括它们的区别和应用场景。文章通过卖票示例展示了如何使用synchronized和Lock实现线程同步,强调了Lock在异常处理、可中断和锁状态检查上的优势。此外,还概述了创建线程的多种方式以及线程同步的重要性。
摘要由CSDN通过智能技术生成

1 Lock接口&synchronized

1.1 多线程编程步骤

1,创建资源类,在资源类中创建成员和操作方法

2,在资源类操作方法中完成
判断
执行
通知

3,防止虚假唤醒等问题

4,创建多个线程,调用资源类的操作方法

1.2 synchronized

1,修饰实例方法: 
作用于当前对象实例加锁,执行方法前需要获取当前对象实例的锁
synchronized void method() {
    //业务代码
}

2,修饰静态方法: 
给当前的类加锁,会作用当前类的所有实例
执行方法前需要获取当前Class的锁
synchronized static void method() {
    //业务代码
}

如果一个线程A调用一个实例对象的非静态syn方法,线程B调用该实例对象的静态syn方法
这是允许的,不会发生互斥现象,因为访问静态syn方法需要的Class锁
访问非静态syn方法需要的是对象锁

3,修饰代码块: 
指定加锁代码块,要进入syn代码块必须要获得指定对象的锁
可以是Class锁,也可以是实例锁
synchronized(this) {
    //业务代码
}

synchronized不可以用于构造方法,构造方法本来就是线程安全的,不需要同步
直接加会报错,显示synchronized不允许加在这里

1.3 Lock和synchronized

Lock锁实现了更广泛的锁操作,比synchronized更多的功能

Lock是一个接口,synchronizedJava的关键字
Lock,有不同实现类如ReentrantLock(可重入锁)

Lock需要手动加锁lock()/释放锁unlock()
最好把unlock()放在finally块中

Lock和synchronized的不同:

1,synchronized发生异常时,会自动释放线程占有的锁,因此不会导致死锁
而Lock发生异常时,如果没有主动通过unlock()释放锁,可能会造成死锁
因此最好在finally块中unlock()释放锁

2,Lock可以让等待锁的线程中断,而synchronized不行
使用syn时等待锁的线程会一直等待下去,不能响应中断

3,Lock可以知道有没有成功获取锁,syn不行

4,Lock可以提高多个线程进行读操作的效率

从性能上来说,如果竞争不激烈,二者的性能相差不多
当竞争非常激烈时,Lock性能远优于syn

1.4 创建线程的多种方式

1,继承Thread2,实现Runnable接口

3,实现Callable接口

4,使用线程池

1.5 使用syn&Lock实现卖票

创建共享的资源类,并对必要操作进行同步:

使用syn完成同步:
public class Ticket {

    private int tickets;

    public Ticket(int tickets) {
        this.tickets = tickets;
    }

    public synchronized void sellTicket() {
        if(tickets > 0) {
            System.out.println(Thread.currentThread().getName() + " 卖出了一张票");
            this.tickets--;
            System.out.println("剩余票数: " + this.tickets);
        } else {
            System.out.println("票已售尽");
        }
    }
    
}

使用Lock完成同步:
public class Ticket {

    // 可重入锁
    private final ReentrantLock lock = new ReentrantLock();

    private int tickets;

    public Ticket(int tickets) {
        this.tickets = tickets;
    }

    public synchronized void sellTicket() {
        lock.lock();
        try {
            if(tickets > 0) {
                System.out.println(Thread.currentThread().getName() + " 卖出了一张票");
                this.tickets--;
                System.out.println("剩余票数: " + this.tickets);
            } else {
                System.out.println("票已售尽");
            }
        } finally {
            lock.unlock();
        }
    }

}

执行:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值