Lock鎖(重點)
傳統的synchronized
/**
* 基本買票例子
* 執行緒就是一個單獨的資源類,沒有任何附屬的操作
* 1、屬性、方法
*/
public class SaleTicketDemo01 {
public static void main(String[] args) {
//併發:多執行緒操作同一個資源類,把資源類丟入執行緒
Ticket ticket = new Ticket();
//@FunctionalInterface函式式介面,jdk1.8之後lambda表示式(引數)->{程式碼}
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;
//買票的方式
//synchronized:本質,佇列,鎖
//鎖物件和class
public synchronized void sale() {
if (number > 0) {
System.out.println(Thread.currentThread().getName() + "賣出了第" + number-- + "張票,剩餘:"+number);
}
}
}
Lock 介面
公平鎖:十分公平:先來後到
非公平鎖:十分不公平:可以插隊(預設)有時會先執行在後的執行時間少的。
public class SaleTicketDemo02 {
public static void main(String[] args) {
Ticket2 ticket2 = new Ticket2();
new Thread(()->{
for (int i = 1;i < 40; i++) ticket2.sale();
},"A").start();
new Thread(()->{
for (int i = 1;i < 40; i++) ticket2.sale();
},"B").start();
new Thread(()->{
for (int i = 1;i < 40; i++) ticket2.sale();
},"C").start();
}
}
//資源類
//Lock
class Ticket2 {
private int number = 30;
Lock lock = new ReentrantLock();
public void sale() {
lock.lock();//加鎖
try {
//業務程式碼
if (number > 0) {
System.out.println(Thread.currentThread().getName() + "賣出了第" + number-- + "張票,剩餘:"+number);
}
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
Synchronized 和 Lock 區別
1、Synchronized 是內建的Java關鍵字,Lock是一個Java類
2、Synchronized 無法判斷獲取鎖的狀態,Lock 可以判斷是否獲取到了鎖
3、Synchronized 會自動釋放鎖,Lock 必須要手動釋放鎖!如果不釋放鎖,會死鎖
4、Synchronized 執行緒1(獲得鎖,阻塞)、執行緒2(等待,傻傻的等待);Lock鎖就不一定會等待下去。
5、Synchronized 可重入鎖(可重入就是說某個執行緒已經獲得某個鎖,可以再次獲取鎖而不會出現死鎖),不可以中斷的,非公平。Lock,可重入鎖,可以判斷鎖,非公平(可以自設定)。
6、Synchronized 適合少量的程式碼同步問題,Lock適合鎖大量的同步程式碼!
鎖是什麼,如何判斷鎖的是誰
本作品採用《CC 協議》,轉載必須註明作者和本文連結