Synchronized
package com.ss;
public class SaleTicketDane01 {
public static void main(String[] args) {
Ticket ticket=new Ticket();
new Thread(()->{
for (int i=1;i<60;i++){
ticket.sale();
}
},"a").start();
new Thread(()->{ for (int i=1;i<60;i++){
ticket.sale();
}},"b").start();
new Thread(()->{ for (int i=1;i<60;i++){
ticket.sale();
}},"c").start();
}
}
class Ticket{
private int number = 50;
public synchronized void sale(){
if (number>0){
System.out.println(Thread.currentThread().getName()+"m"+(number--)+"p"+"剩"+number);
}
}
}
Lock
-
new ReentrantLock(); //new一个锁
-
lock.lock(); //加锁
-
finally=> lock.unlock(); //解锁
package com.ss;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SaleTicketDane02 {
public static void main(String[] args) {
Ticket2 ticket=new Ticket2();
new Thread(()->{for (int i=1;i<60;i++)ticket.sale(); },"a").start();
new Thread(()->{for (int i=1;i<60;i++)ticket.sale(); },"b").start();
new Thread(()->{for (int i=1;i<60;i++)ticket.sale(); },"c").start();
}
}
class Ticket2{
private int number = 50;
Lock lock=new ReentrantLock();
public void sale(){
lock.lock();
try {
if (number>0){
System.out.println(Thread.currentThread().getName()+"m"+(number--)+"p"+"剩"+number);
} } catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
Synchronized和Lock的区别
- Synchronized 内置的java关键字, Lock是一个Java类
- Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
- Synchronized 会自动释放锁,lock必须手动释放锁!如果不释放锁,死锁
- Synchronized 线程1(获得锁,阻塞),线程2(等待,傻傻的等);Lock锁不一定会等待下去;
- Synchronized 可重入锁,不可以中断的,非公平 ; Lock 可重入锁,可以判断锁,非公平(可以自己设置);
- Synchronized 适合锁少量的代码同步问题,Lock 适合所大量的同步代码
什么是死锁
死锁:是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
什么是活锁
活锁:是指线程1可以使用资源,但它很礼貌,让其他线程先使用资源,线程2也可以使用资源,但它很绅士,也让其他线程先使用资源。这样你让我,我让你,最后两个线程都无法使用资源。
什么是饥饿
饥饿:是指如果线程T1占用了资源R,线程T2又请求*R,于是T2等待。T3也请求资源R,当T1释放了R上的*后,系统首先批准了T3的请求,T2仍然等待。然后T4又请求*R,当T3释放了R上的*之后,系统又批准了T4的请求……,T2可能永远等待