持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
2.1、Synchronized
是一种同步锁,修饰的对象有以下几种:
1、修饰一个代码块,被修饰的代码块称为同步语句块,其作用范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象。
2、修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象。
synchronized并不属于方法定义的一部分。因此,synchronized关键字不能被继承。
synchronized卖票小实例
/**
* @author rop
* @since 2022/10/9 21:34
*/
public class SaleTicket {
public static void main(String[] args) {
// 第二步:创建多个线程,调用资源类的操作方法
Ticket ticket = new Ticket();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.sale();
}
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.sale();
}
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.sale();
}
}
}, "C").start();
}
}
// 第一步:创建资源类,定义属性和操作方法
class Ticket {
// 票数
private int number = 30;
// 操作方法:卖票
// public void sale() {
public synchronized void sale() {
// 判断
if (number > 0) {
System.out.println(Thread.currentThread().getName()
+ "卖出了第 " + ( number-- ) + " 张票,还剩:" + number + "张");
}
}
}
2.2、什么是Lock接口
Lock锁实现提供了比使用同步方法和语句可以获得的更广泛的锁操作。它们允许更灵活的结构,可能具有非常不同的属性,并且可能支持多个关联的条件对象。Lock提供了比synchronized更多的功能。
Lock和Synchronized的区别
- Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
- Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
2.3、Lock实现可重入锁
private final ReentrantLock lock = new ReentrantLock();
再用这把锁上锁和解锁对应的操作
2.4、创建多线程的多种方式
- Thread
- Runnable
- Callable
2.5、使用Lock实现卖票
/**
* @author rop
* @since 2022/10/9 23:04
*/
public class LTicketSale {
public static void main(String[] args) {
// 第二步:创建多个线程,调用资源类的操作方法
LTicket ticket = new LTicket();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.sale();
}
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.sale();
}
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 40; i++) {
ticket.sale();
}
}, "C").start();
}
}
// 第一步:创建资源类,定义属性和操作方法
class LTicket {
// 票数量
private int number = 30;
// 创建可重入锁
private final ReentrantLock lock = new ReentrantLock();
// 卖票
public void sale() {
// 上锁
lock.lock();
try {
if (number > 0) {
System.out.println(Thread.currentThread().getName() + "卖了第" + ( number-- ) + "张票,还剩" + number + "张");
}
} finally {
// 解锁
lock.unlock();
}
}
}