lock 和condition條件變數的使用
注意點:1.作為物件鎖,寫在Account裡面和外面不一樣,寫在裡面是該類方法只會公用該類物件的鎖,寫在外面表示所有物件都公用那一個鎖,不同使用者公用一個鎖,顯然是不對的。所以寫在裡面表示每個使用者的取錢和存錢共享鎖,和其它的使用者物件沒有關係,因為公用的鎖不一樣。
2. 對於lock 鎖一定注意不能用static 修飾,這樣和寫在Account 外面是一樣的,其它的使用者也可以呼叫另外一個使用者的lock物件做為鎖,影響到其它使用者了,也會導致執行緒報錯。
3. 對於百萬使用者同時存錢取錢的,用lock ,同步量少的用syncronized,這裡測試的lock 為5.8秒,sy為7.3秒
@RequestMapping(value="/testMoney3",method=RequestMethod.GET)
@ResponseBody
public int testThread3() {
long time =System.currentTimeMillis();
int i=1000000;
int money=0;
while(i>2) {
MyAccount myAccount=new MyAccount();
new Thread() {
public void run() {
myAccount.saveMoney(m);
// System.out.println("baocun:"+myAccount.getMoney());
myAccount.delMoney(m);
// System.out.println("shanchu:"+myAccount.getMoney());
}
}.start();
i--;
money=myAccount.getMoney();
}
// int money=myAccount.getMoney();
// System.out.println(myAccount.getMoney());
long time2 =System.currentTimeMillis();
System.out.println("用時:"+(time2-time));
return money;
}
// @RequestMapping(value="/testMoneyOther",method=RequestMethod.GET)
// @ResponseBody
// public int testThread2() {
// int i=1000000;
// int money=0;
// long time =System.currentTimeMillis();
// MyAccount myAccount=new MyAccount();
// while(i>2) {
// myAccount.saveMoney(m);
// myAccount.delMoney(m);
// money=myAccount.getMoney();
// System.out.println(myAccount.getMoney());
// i--;
// }
// long time2 =System.currentTimeMillis();
// System.out.println("用時:"+(time2-time)/1000);
// return money;
// }
package com.example.demo.lockp;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.springframework.stereotype.Component;
public class MyAccount {
private int money =10000;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private Obj obj = new Obj();
private boolean flage=true;
public int getMoney() {
return money;
}
public Obj getObj() {
return obj;
}
public void saveMoney(int m) {
lock.lock();
try {
if(obj.getState()==1) {
money+=m;
obj.setState(2);
condition.signal();
}else if(obj.getState()==2){
condition.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void delMoney(int m) {
lock.lock();
while(money<100&&money-m<0) {
flage=false;
}
if(!flage) {
try {
throw new Exception("ssss");
} catch (Exception e) {
e.printStackTrace();
}
}
try {
if(obj.getState()==2) {
money-=m;
obj.setState(1);
condition.signal();
}else if(obj.getState()==1){
condition.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
// //設定引數
// public void setParm(Obj obj, Lock lock, Condition condition) {
// this.obj = obj;
// this.lock = lock;
// this.condition = condition;
// }
public void saveMoney123(int m) {
synchronized (this) {
money+=m;
notifyAll();
}
}
public void delMoney123(int m) {
synchronized (this) {
money-=m;
notifyAll();
}
}
}
package com.example.demo.lockp;
import org.springframework.stereotype.Component;
public class Obj {
public int state = 1;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}