Synchronized的使用
以卖票为例
//基本的卖票例子
/*
真正的多线程开发,公司中的开发,降低耦合性
线程就是一个单独的资源类,没有任何附属的操作
1.属性、方法
*/
public class SaleTicketDemo01 {
public static void main(String[] args) {
//多个线程操作同一个资源类
Ticket ticket = new Ticket();
//@FunctionalInterface 函数式接口,jdk1.8 lambda表达式 (参数)->{ 代码 }
new Thread(()->{
for (int i = 0; i < 60; i++) {
ticket.sale();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 60; i++) {
ticket.sale();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 60; i++) {
ticket.sale();
}
},"C").start();
}
}
class Ticket {
//属性、方法
private int number = 50;
//卖票的方式
//synchronized 本质:队列,锁
public synchronized void sale(){
if (number>0){
System.out.println(Thread.currentThread().getName()+"卖出了1张票,剩余"+--number+"张票");
}
}
}
Lock锁
需要手动加锁,释放锁
Lock锁是一个接口,他有三个实现类:
- ReentrantLock类
- ReentrantReadWriteLock.ReadLock
- ReentrantReadWriteLock.WriteLock
以卖票为例
//基本的卖票例子
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
真正的多线程开发,公司中的开发,降低耦合性
线程就是一个单独的资源类,没有任何附属的操作
1.属性、方法
*/
public class SaleTicketDemo02 {
public static void main(String[] args) {
//多个线程操作同一个资源类
Ticket2 ticket = new Ticket2();
//@FunctionalInterface 函数式接口,jdk1.8 lambda表达式 (参数)->{ 代码 }
new Thread(()->{
for (int i = 0; i < 5; i++) {
ticket.sale();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
ticket.sale();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
ticket.sale();
}
},"C").start();
}
}
class Ticket2 {
//属性、方法
private int number = 15;
Lock lock = new ReentrantLock();
//lock三部曲
//1. new ReentrantLock()
//2.lock.lock(); //加锁
//3.finally =>lock.unlock(); //解锁
public synchronized void sale(){
lock.lock(); //加锁
try {
//业务代码
if (number>0){
System.out.println(Thread.currentThread().getName()+"卖出了1张票,剩余"+--number+"张票");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock(); //解锁
}
}
}
Lock锁和synchronized的区别
- Synchronized是内置Java关键字;Lock是一个Java类。
- Synchronized无法判断获取锁的状态;Lock可以判断是否获取到了锁。(boolean b = lock.tryLock();)
- Synchronized会自动释放锁;Lock必须要手动释放锁,如果不释放锁,死锁。
- Synchronized线程1获得锁阻塞时,线程2会一直等待下去;Lock锁线程1获得锁阻塞时,线程2等待足够长的时间后中断等待,去做其他的事。
- Synchronized可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可手动设置为公平锁)。
- Synchronized适合锁少量的代码同步问题;Lock适合锁大量的同步代码。