Synchronized同步锁:
实现例子:抢票
public class SaleTicketTest {
public static void main(String[] args) {
//并发:多个线程操控同一个资源类
Ticket ticket=new Ticket();
//lambda表达式:(参数)->{代码},这里的lambda简化的就是Runnable接口
new Thread(()->{
for (int i = 1; i <= 50; i++) {
ticket.sale();
}
},"A").start();
new Thread(()->{
for (int i = 1; i <=50; i++) {
ticket.sale();
}
},"B").start();
new Thread(()->{
for (int i = 1; i <= 50; i++) {
ticket.sale();
}
},"C").start();
}
}
//资源类 OOP
class Ticket{
private int numbers=50;
//synchronized同步锁,本质就是排队使用该方法
public synchronized void sale(){
if(numbers>0){
System.out.println(Thread.currentThread().getName()+"卖出了"+(numbers--)+"票,剩余"+numbers+"张票");
}
}
}
Lock锁:
Lock接口(在JUC包里)
ReentrantLock
实现类:
构造方法:
公平锁:先来先使用原则。
非公平锁:没有排队。
实现例子:
public class SaleTicketLock {
public static void main(String[] args) {
TicketLock ticket=new TicketLock();
//lambda表达式:(参数)->{代码},这里的lambda简化的就是Runnable接口
new Thread(()->{
for (int i = 1; i <= 50; i++) {
ticket.sale();
}
},"A").start();
new Thread(()->{
for (int i = 1; i <=50; i++) {
ticket.sale();
}
},"B").start();
new Thread(()->{
for (int i = 1; i <= 50; i++) {
ticket.sale();
}
},"C").start();
}
}
//Lock锁
class TicketLock{
private int numbers=50;
//ReentranLock可重入锁
Lock lock=new ReentrantLock();
public void sale(){
lock.lock();//加锁
try{//业务代码
if(numbers>0){
System.out.println(Thread.currentThread().getName()+"卖出了"+(numbers--)+"票,剩余"+numbers+"张票");
}
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();//解锁
}
}
}
Synchronized同步锁和Lock锁的区别:
1:Synchronized是内置的Java关键字,Lock是一个Java接口。
2:Synchronized无法判断获取锁的状态,Lock可以判断是否获取到了锁。
3:Synchronized会自动释放锁,Lock需要手动开启和释放锁,如果没有释放就会死锁。
4:获得Synchronized锁的线程如果阻塞,其他线程便会一直等待;Lock里有trylock()
方法可以尝试获得锁,不会一直等待。
5:Synchronized是可重入锁,不可以中断,非公平锁;Lock是可重入锁,可以判断锁,非公平锁(可以自己设置为公平锁)。
6:Synchronized适合锁少量的同步代码;Lock适合锁大量的同步代码。