內(nèi)部鎖Synchronized與重入鎖ReentrantLock,一次都只允許一個線程訪問一個資源田炭,而信號量卻可以指定多個線程近她,同時訪問一個資源及其副本。
用代碼模擬停車場:
/*
* 車位信息
*/
publicclassSpace {
privateintid;//車位編號
privatebooleanused=false;//是否已占用竟宋;
publicSpace(intid,booleanused){
this.id=id;
this.used=used;
}
publicsynchronizedbooleanisUsed() {
returnused;
}
publicsynchronizedvoidsetUsed(booleanused) {
this.used=used;
}
publicintgetId() {
returnid;
}
}
/*
* 停車
*/
publicclassParkextendsSpaceimplementsRunnable {
privateSemaphoresemaphore=null;
publicPark(intid,booleanused,Semaphoresemaphore) {
super(id,used);
this.semaphore=semaphore;
}
@Override
publicsynchronizedvoidrun() {
try{
this.setUsed(true);
System.out.println("當(dāng)前車位被占用"+this.getId()+"毫秒,id="+this.getId()+";車位狀態(tài),used="+this.isUsed());
Thread.sleep(this.getId());
this.setUsed(false);
this.semaphore.release();
}catch(Exceptione) {
e.printStackTrace();
}
}
}
/*
* 停車場
*/
publicclassParkingLot {
privatePark[]parks=null;
/*
* count個空閑的車位
*/
publicParkingLot(intcount,Semaphoresemaphore){
this.parks=newPark[count];
for(inti=0;i
parks[i]=newPark(i+1,false,semaphore);
}
}
/*
* 返回空閑的車位
*/
publicList getFreeSpace(intcount){
ArrayListal=newArrayList();
intjs=0;
for(inti=0;i
if(parks[i].isUsed()==false){//空閑的
al.add(parks[i]);
js++;
if(js>=count){
break;
}
}
}
returnal;
}
/*
* 把車停到某個車位
*/
publicvoidparking(Parkpark){
try{
if(park.isUsed()==false){//空閑的
Threadth=newThread(park);
th.start();//開始占用這個車位提完;
}else{
System.out.println("沒有找到空閑的車位");
}
}catch(Exceptione){
e.printStackTrace();
}
}
publicstaticvoidmain(String[]args)throwsInterruptedException{
Semaphoresemaphore=newSemaphore(5);//5個信號量,相當(dāng)于允許5個線程同時訪問共享資源丘侠;
ParkingLotparkingLot=newParkingLot(5,semaphore);//停車場有5個車位
intpc=0;//批次
while(pc<20){
Randomrd=newRandom();
intcount=rd.nextInt(5);//場外有了count輛車
Listal=parkingLot.getFreeSpace(count);
semaphore.acquire(al.size());
pc++;
System.out.println("可以安排"+al.size()+"輛車進(jìn)入停車場,這是第"+pc+"批");
intfact=al.size();//實際進(jìn)場的車輛數(shù)
for(inti=0;i
parkingLot.parking(al.get(i));
}
}
}
}