在這就簡單說下鎖重要性吧,鎖一般應用在安全方面。如項目中與錢相關的操作,單機情況下是基本沒安全方面的問題。像網站這種,情況一:線程不安全,當多個請求同時到達,他們可能同時執行,我們的普通限制可能會失效,取款金額就可能出現負數(這一般是不允許出現的情況)。情況一:線程安全,我這指的是加鎖,當多個請求同時到達,這樣就能達到一條一條請求執行的效果。
案例(有鎖的)
包:com.gx.mi_dome
三個類: Jfdh_thread_lock( 鎖的實作) 、Jfdh_thread(線程同步鎖 繼承Thread線程 ) 、 zhixing(主方法函數)
zhixing.java代碼
package com.gx.mi_dome;
import com.gx.mi_dome.Jfdh_thread;
import com.gx.mi_dome.Jfdh_thread_lock;
public class zhixing {
public static void main(String[] args) {
Jfdh_thread_lock zhanghuone=new Jfdh_thread_lock(1000);//定義 使用者擁有1000積分
//第二種:循環
int BB=1;
int A_CS=13;
for(int a=0;a< BB;a++){
BB++;
if(zhanghuone.getDhjf() < A_CS){//目前剩餘積分 小于 目前所兌換積分
System.out.println("兌換物品積分大于剩餘積分");
break;//結束循環 小智
}
Jfdh_thread takeMoney4=new Jfdh_thread(zhanghuone, A_CS);//建立線程對象 執行兌換積分方法
A_CS=A_CS+3;//每次兌換積分加3
// Jfdh_thread takeMoney2=new Jfdh_thread(zhanghuone, B_CS);//takeMoney2.start();
takeMoney4.start();//start 開始
//等待線程完成 // 線程休眠1000ms(一秒)
try {Thread.sleep(500);} catch (InterruptedException e) {//補捉 中斷故障異常
System.out.println("中斷故障異常");
}
}
System.out.println("目前剩餘積分:"+zhanghuone.getDhjf());
}
}
Jfdh_thread_lock.java代碼
package com.gx.mi_dome;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* 鎖的實作(ReentrantLock 重入鎖)
*
* @author 星月
*
*/
public class Jfdh_thread_lock {
/*
* 重入鎖(ReentrantLock)是一種遞歸無阻塞的同步機制。以前一直認為它是synchronized的簡單替代,
* 而且實作機制也相差太遠。不過最近實踐過程中發現它們之間還是有着天壤之别。
* 它提供了lock()方法:如果該鎖定沒有被另一個線程保持,則擷取該鎖定并立即傳回,将鎖定的保持計數設定為 1。
* 如果目前線程已經保持該鎖定,則将保持計數加 1,并且該方法立即傳回。
* 如果該鎖定被另一個線程保持,則出于線程排程的目的,禁用目前線程,并且在獲得鎖定之前,
* 該線程将一直處于休眠狀态,此時鎖定保持計數被設定為 1
*/
// ReentrantLock擷取鎖定與三種方式:
// a) lock(), 如果擷取了鎖立即傳回,如果别的線程持有鎖,目前線程則一直處于休眠狀态,直到擷取鎖
// b) tryLock(), 如果擷取了鎖立即傳回true,如果别的線程正持有鎖,立即傳回false;
// c) tryLock(long timeout,TimeUnit unit), 如果擷取了鎖定立即傳回true,如果别的線程正持有鎖,會等待參數給定的時間,在等待的過程中,如果擷取了鎖定,就傳回true,如果等待逾時,傳回false;
// d) lockInterruptibly:如果擷取了鎖定立即傳回,如果沒有擷取鎖定,目前線程處于休眠狀态,直到或者鎖定,或者目前線程被别的線程中斷
// Thread.setPriority(10); 就算設定線程優先等級 (最大:10 ,最小:1) 也不一定先執行 這涉及cpu工作原理
private final ReentrantLock lock=new ReentrantLock();//建立鎖對象
/**
* 積分
*/
private Integer dhjf;
public Integer getDhjf() {
return dhjf;
}
public void setDhjf(Integer dhjf) {
this.dhjf = dhjf;
}
//定義使用者積分
public Jfdh_thread_lock(Integer dhjf) {
this.dhjf = dhjf;
}//帶參構造方法
//方法函數 主要鎖的代碼塊
public void jfdh_Method(Integer dhjf_CS) {
lock.lock();// 加鎖
if (dhjf_CS <= this.dhjf) {
// 模拟取積分成功
System.out.println("兌換積分" + dhjf_CS + "分");
// 線程暫停 10ms 模拟網絡傳輸
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 修改目前擁有積分
this.dhjf = this.dhjf - dhjf_CS;
System.out.println("剩餘積分為:" + this.dhjf);
} else {
System.out.println("積分兌換失敗");
}
lock.unlock();//解鎖
}
}
Jfdh_thread.java代碼
package com.gx.mi_dome;
import com.gx.mi_dome.Jfdh_thread_lock;
/**
*
* 積分兌換線程同步鎖 繼承Thread線程
*
* @author 星月
*
*/
public class Jfdh_thread extends Thread{
/**
* 積分線程鎖對象
*/
private Jfdh_thread_lock jfdh_thread_lock;
/**
* 積分
*/
private Integer dhjf;
//AccountLock 同步鎖
public Jfdh_thread(Jfdh_thread_lock jfdh_thread_lock_CS,Integer dhjf_CS){
this.jfdh_thread_lock=jfdh_thread_lock_CS;
this.dhjf=dhjf_CS;
}
/**
* 模拟積分兌換方法
*/
@Override
public void run() {
jfdh_thread_lock.jfdh_Method(dhjf);
}
}
自己寫的一個案例,新手勿噴。