用java智能锁远程,从生产者-消费者模型了解线程、同步、锁(java)
代碼主要包括4個(gè)類和1個(gè)測(cè)試類:
1、Egg 類: 雞蛋,可以由生產(chǎn)者放入到籃子中,供消費(fèi)者消費(fèi)食用。
2、Blanket 類:一個(gè)籃子,最多能裝5個(gè)雞蛋。
3、Producer 類: 生產(chǎn)者(可以有1個(gè)或多個(gè),但一次只能由一個(gè)人放入1個(gè)),負(fù)責(zé)把雞蛋放入到籃子中。
4、Customer 類 :消費(fèi)者(可以有1個(gè)或多個(gè),但一次只能由一個(gè)人吃1個(gè)), 會(huì)把籃子里的雞蛋取走食用。
5、Tester 類 : 用于測(cè)試,可設(shè)置多個(gè)生產(chǎn)者和消費(fèi)者。
1、Egg類,有一個(gè)ID屬性,用于標(biāo)識(shí)生產(chǎn)和消費(fèi)的雞蛋是哪一個(gè)雞蛋,直觀一點(diǎn):
public class Egg {
int id;
public Egg (int id) {
this.id = id;
}
public String toString () {
return "雞蛋" + id;
}
}
2、Blanket類,其中的放入雞蛋(add)和吃雞蛋(eat)方法使用了同步鎖,即同一時(shí)間內(nèi)只能由一個(gè)人操作籃子,放入雞蛋或吃雞蛋:
public class Blanket {
int count = 0;
Egg [] eggs = new Egg[5];
public synchronized void eat() {
while(count == 0){
try{
this.wait();//當(dāng)籃子里雞蛋數(shù)目為0時(shí),等待生產(chǎn)者放入雞蛋
}catch(InterruptedException ex) {
ex.printStackTrace();
}
}
this.count--;
System.out.println(Thread.currentThread().getName() + "吃了"+this.eggs[count].toString());
this.notifyAll();
}
public synchronized void add(Egg e) {
while(count == 5){
try {
this.wait();//當(dāng)籃子里有5個(gè)雞蛋時(shí),先休息
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "生產(chǎn)了:" + e.toString());
this.eggs[count] = e;//生產(chǎn)雞蛋
count++;
this.notifyAll();//喚醒消費(fèi)者
}
}
3、Producer 類,繼承Runable的生產(chǎn)者,在條件允許(籃子雞蛋未滿)的情況不停的放入雞蛋:
public class Producer implements Runnable{
Blanket blanket;
public Producer(Blanket blanket) {
this.blanket = blanket;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
int i = blanket.count;
Egg e = new Egg(i);
blanket.add(e);
try {
Thread.sleep((int)(Math.random()*1000));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
4、Customer 類 ,繼承Runable 的消費(fèi)者,在籃子里有雞蛋的時(shí)候就會(huì)去取出來(lái)吃:
public class Customer implements Runnable {
Blanket blanket;
public Customer(Blanket blanket) {
this.blanket = blanket;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
blanket.eat();
try{
Thread.sleep((int)(Math.random()*2800));
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
5、Tester 類,用于進(jìn)行測(cè)試,定義一個(gè)籃子,和1個(gè)或多個(gè)生產(chǎn)者,消費(fèi)者,使這些生產(chǎn)者和消費(fèi)者共用一個(gè)籃子:
public class Tester {
public static void main(String[] args) {
// TODO Auto-generated method stub
Blanket b = new Blanket();
Producer p = new Producer(b);
Producer q = new Producer(b);
Customer c = new Customer(b);
Customer d = new Customer(b);
Customer e = new Customer(b);
Customer f = new Customer(b);
new Thread(p,"生產(chǎn)者A").start();
new Thread(q,"生產(chǎn)者B").start();
new Thread(c,"消費(fèi)者A").start();
new Thread(d,"消費(fèi)者B").start();
new Thread(e,"消費(fèi)者C").start();
new Thread(f,"消費(fèi)者D").start();
}
}
上面的程序運(yùn)行效果如下:
生產(chǎn)者A生產(chǎn)了:雞蛋0
消費(fèi)者A吃了雞蛋0
生產(chǎn)者B生產(chǎn)了:雞蛋0
消費(fèi)者B吃了雞蛋0
生產(chǎn)者A生產(chǎn)了:雞蛋0
消費(fèi)者D吃了雞蛋0
生產(chǎn)者A生產(chǎn)了:雞蛋0
消費(fèi)者C吃了雞蛋0
生產(chǎn)者A生產(chǎn)了:雞蛋0
生產(chǎn)者B生產(chǎn)了:雞蛋1
消費(fèi)者D吃了雞蛋1
生產(chǎn)者B生產(chǎn)了:雞蛋1
生產(chǎn)者A生產(chǎn)了:雞蛋2
生產(chǎn)者A生產(chǎn)了:雞蛋3
生產(chǎn)者A生產(chǎn)了:雞蛋4
消費(fèi)者B吃了雞蛋4
生產(chǎn)者B生產(chǎn)了:雞蛋5
消費(fèi)者A吃了雞蛋5
生產(chǎn)者A生產(chǎn)了:雞蛋5
消費(fèi)者B吃了雞蛋5
它將不停的運(yùn)行下去,不會(huì)出現(xiàn)死鎖。代碼的同步(synchronized)模塊設(shè)置在共用的資源(籃子)中,每次只能由一名生產(chǎn)者或者消費(fèi)者操作籃子,其他人處于等待(wait)狀態(tài),等它操作完了,它才通知其他人(notifyAll),其它人則通過(guò)競(jìng)爭(zhēng),然后只有一個(gè)競(jìng)爭(zhēng)勝利的可以操作籃子,如此循環(huán)。
總結(jié)
以上是生活随笔為你收集整理的用java智能锁远程,从生产者-消费者模型了解线程、同步、锁(java)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php str_replace多个参数,
- 下一篇: oracle更改文件,Oracle修改数