
線程安全問(wèn)題
什么是線程安全問(wèn)題?
多個(gè)線程操作同一個(gè)共享資源的時(shí)候可能會(huì)出現(xiàn)線程安全問(wèn)題。
如何解決線程安全問(wèn)題?
使用線程同步
線程同步
什么是線程同步?
線程同步是多個(gè)線程同時(shí)訪問(wèn)同一個(gè)資源。
線程同步的作用:
就是為了解決線程安全問(wèn)題的方案
如何實(shí)現(xiàn)線程同步?
把共享資源進(jìn)行上鎖,每次只能一個(gè)線程進(jìn)入訪問(wèn)完畢后,其他線程才能繼續(xù)訪問(wèn)。
線程同步的方式有三種:
1.同步代碼塊
2.同步方法
3.lock顯示鎖 同步代碼塊
同步代碼塊
作用:把出現(xiàn)線程安全問(wèn)題的核心代碼給上鎖,每次只能一個(gè)線程進(jìn)入,執(zhí)行完畢以后自動(dòng)上鎖,其他線程才可以進(jìn)來(lái)執(zhí)行。
格式:
synchronized(鎖對(duì)象){
//訪問(wèn)共享資源的核心代碼
}
鎖對(duì)象建議使用共享資源
在實(shí)例方法中建議使用this作為鎖對(duì)象。此時(shí)this正好是共享資源!
在靜態(tài)方法中建議使用類名.class字節(jié)碼作為鎖對(duì)象。
synchronized (this){
if(this.money >= money){
System.out.println(name+"來(lái)取錢(qián),吐出:"+money);
this.money -= money;
System.out.println(name+"來(lái)取錢(qián)"+money+"成功,取錢(qián)后剩余:"+this.money;
}else{
System.out.println(name+"來(lái)取錢(qián),余額不足,剩余"+this.money;
}
}
//張三來(lái)取錢(qián),吐出:10000
//張三取錢(qián)成功,取錢(qián)后剩余0
//李四來(lái)取錢(qián),余額不足,剩余0
同步方法
作用:
把出現(xiàn)線程安全問(wèn)題的核心方法給鎖起來(lái)
每次只能使一個(gè)線程進(jìn)入訪問(wèn),其他線程必須在方法外面等待。
用法:
直接給方法加上一個(gè)修飾符 synchronized
public synchronized void ThreadDemo(){
if(this.money >= money){
System.out.println(name+"來(lái)取錢(qián),吐出:"+money);
this.money -= money;
System.out.println(name+"來(lái)取錢(qián)"+money+"成功,取錢(qián)后剩余:"+this.money;
}else{
System.out.println(name+"來(lái)取錢(qián),余額不足,剩余"+this.money;
}
}
lock顯示鎖
java.util.concurrent.locks.Lock機(jī)制提供了比synchronized代碼塊和synchronized方法更廣泛的鎖操作,同步代碼塊/同步方法具有的功能Lock鎖都有,除此之外更強(qiáng)大更方便
Lcok鎖也稱同步鎖,加鎖與釋放鎖方法化了,如下:
--public void lock() //:加同步鎖
--public void unlock() //:釋放同步鎖
實(shí)例:
//創(chuàng)建一把鎖
private final Lock lock = new ReentrantLock();
lock.lock(); //上鎖
try{
if(this.money >= money){
System.out.println(name+"來(lái)取錢(qián),吐出:"+money);
this.money -= money;
System.out.println(name+"來(lái)取錢(qián)"+money+"成功,取錢(qián)后剩余:"+this.money;
}else{
System.out.println(name+"來(lái)取錢(qián),余額不足,剩余"+this.money;
}catch (Exception e){
e.printStackTrace();
}finally{
lock.unlock(); //解鎖
}
}
分類: [Java基礎(chǔ)]