1、獲取從頁面?zhèn)鬟^來的參數(shù)。
成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),和龍企業(yè)網(wǎng)站建設(shè),和龍品牌網(wǎng)站建設(shè),網(wǎng)站定制,和龍網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,和龍網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
2、把參數(shù)添加到Map集合中。
3、進行參數(shù)類型的判斷和拼接。
4、這樣即可用java配置兩個參數(shù)代碼。
myeclipse管理多個java源代碼是通過package實現(xiàn)的。
如果是在同一個包里的多個類的話,執(zhí)行的時候只要運行有Main函數(shù)的類就可以了。
如果是不同包里的多個類的話,在類文件里用import語句把在這個類里要用到的類包含進來,然后執(zhí)行有Main函數(shù)的類就可以了。
public?class?ProduceConsumerDemo?{
public?static?void?main(String[]?args)?{
//?1.創(chuàng)建資源
Resource?resource?=?new?Resource();
//?2.創(chuàng)建兩個任務(wù)
Producer?producer?=?new?Producer(resource);
Consumer?consumer?=?new?Consumer(resource);
//?3.創(chuàng)建線程
/*
*?多生產(chǎn)多消費產(chǎn)生的問題:重復生產(chǎn)、重復消費
*/
Thread?thread0?=?new?Thread(producer);
Thread?thread1?=?new?Thread(producer);
thread0.setName("生產(chǎn)者(NO0)");
thread1.setName("生產(chǎn)者(NO1)");
Thread?thread2?=?new?Thread(consumer);
Thread?thread3?=?new?Thread(consumer);
thread2.setName("消費者(NO2)");
thread3.setName("消費者(NO3)");
thread0.start();
thread1.start();
thread2.start();
thread3.start();
}
}
class?Resource?{
private?String?name;
private?int?count?=?1;
//?定義標記
private?boolean?flag;
//?提供給商品賦值的方法
public?synchronized?void?setName(String?name)?{//?thread0,?thread1在這里運行
while?(flag)//?判斷標記為true,執(zhí)行wait等待,為false則生產(chǎn)
/*
*?這里使用while,而不使用if的理由如下:
*?
*?thread0有可能第二次也搶到鎖的執(zhí)行權(quán),判斷為真,則有面包不生產(chǎn),所以接下來執(zhí)行等待,此時thread0在線程池中。
*?接下來活的線程有3個(除了thread0),這三個線程都有可能獲取到執(zhí)行權(quán).
*?假設(shè)thread1獲得了執(zhí)行權(quán),判斷為真,則有面包不生產(chǎn),執(zhí)行等待。此時thread1又進入到了線程池中。
*?接下來有兩個活的線程thread2和thread3。?假設(shè)thread2又搶到了執(zhí)行權(quán),所以程序轉(zhuǎn)到了消費get處……
*/
try?{
this.wait();//這里wait語句必須包含在try/catch塊中,拋出異常。
}?catch?(InterruptedException?e)?{
e.printStackTrace();
}
this.name?=?name?+?count;//?第一個面包
count++;//?2
System.out.println(Thread.currentThread().getName()?+?this.name);//?thread0線程生產(chǎn)了面包1
//?生產(chǎn)完畢,將標記改成true.
flag?=?true;//?thread0第一次生產(chǎn)完面包以后,將標記改為真,表示有面包了
//?喚醒消費者(這里使用notifyAll而不使用notify的原因在下面)
this.notifyAll();//?第一次在這里是空喚醒,沒有意義
}
/*
*?通過同步,解決了沒生產(chǎn)就消費的問題
*?生產(chǎn)完以后,生產(chǎn)者釋放了this鎖,此時,生產(chǎn)者和消費者同時去搶鎖,又是生產(chǎn)者搶到了鎖,所以就出現(xiàn)了一直生產(chǎn)的情況。
*?與“生產(chǎn)一個就消費一個的需求不符合”?等待喚醒機制?wait();該方法可以使線程處于凍結(jié)狀態(tài),并將線程臨時存儲到線程池
*?notify();喚醒指定線程池中的任意一個線程。?notifyAll();喚醒指定線程池中的所有線程
*?這些方法必須使用在同步函數(shù)中,因為他們用來操作同步鎖上的線程上的狀態(tài)的。
*?在使用這些方法時候,必須標識他們所屬于的鎖,標識方式就是鎖對象.wait();?鎖對象.notify();?鎖對象.notifyAll();
*?相同鎖的notify()可以獲取相同鎖的wait();
*/
public?synchronized?void?getName()?{//?thread2,thread3在這里運行
while?(!flag)
/*
*?……接著上面的程序執(zhí)行分析?thread2拿到鎖獲取執(zhí)行權(quán)之后,判斷!flag為假,則不等待,直接消費面包1,輸出一次.
*?消費完成之后將flag改為假?接下來又喚醒了thread0或者thread1生產(chǎn)者中的一個
*?假設(shè)又喚醒了thread0線程,現(xiàn)在活的線程有thread0,thread2,thread3三個線程
*?假設(shè)接下來thread2又搶到了執(zhí)行權(quán),判斷!flag為真,沒面包了,停止消費,所以thread2執(zhí)行等待.
*?此時活著的線程有thread0和thread3。
*?假設(shè)thread3得到了執(zhí)行權(quán),拿到鎖之后進來執(zhí)行等待,此時活著的線程只有thread0.
*?所以thread0只能搶到執(zhí)行權(quán)之后,生產(chǎn)面包2,將標記改為true告訴消費者有面包可以消費了。
*?接下來執(zhí)行notify喚醒,此時喚醒休眠中的3個線程中的任何一個都有可能。
*?如果喚醒了消費者thread2或者thread3中的任何一個,程序都是正常。如果此時喚醒thread1則不正常。
*?如果喚醒了thread1,此時活著的線程有thread0和thread1兩個線程。
*?假設(shè)thread0又獲得了執(zhí)行權(quán),判讀為真有面包,則又一次執(zhí)行等待。
*?接下來只有thread1線程有執(zhí)行權(quán)(此時沒有判斷標記直接生產(chǎn)了,出錯了),所以又生產(chǎn)了面包3。?在這個過程中,面包2沒有被消費。
*?這就是連續(xù)生產(chǎn)和消費容易出現(xiàn)的問題。
*?
*?原因:被喚醒的線程沒有判斷標記就開始執(zhí)行了,導致了重復的生產(chǎn)和消費發(fā)生。
*?
*?解決:被喚醒的線程必須判斷標記,使用while循環(huán)標記,而不使用if判斷的理由。
*?
*?但是接下來會出現(xiàn)死鎖,原因在于:
*?上面的程序中thread0在執(zhí)行notify的時候喚醒了thread1,而此時thread2和thread3兩個消費者線程都處于等待狀態(tài)
*?thread1在執(zhí)行while判斷語句之后判斷為真,則執(zhí)行等待,此時所有的線程都處于凍結(jié)等待狀態(tài)了。
*?
*?原因:本方線程在執(zhí)行喚醒的時候又一次喚醒了本方線程,而本方線程循環(huán)判斷標記又繼續(xù)等待,而導致所有的線程都等待。
*?
*?解決:本方線程喚醒對方線程,?可以使用notifyAll()方法
*? 喚醒之后,既有本方,又有對方,但是本方線程判斷標記之后,會繼續(xù)等待,這樣就有對方線程在執(zhí)行。
*/
try?{
this.wait();
}?catch?(InterruptedException?e)?{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()??+?this.name);
//?將標記改為false
flag?=?false;
//?喚醒生產(chǎn)者
this.notify();
}
}
//?生產(chǎn)者
class?Producer?implements?Runnable?{
private?Resource?resource;
public?Producer(Resource?resource)?{
this.resource?=?resource;
}
public?void?run()?{
while?(true)?{
resource.setName("面包");
}
}
}
//?消費者
class?Consumer?implements?Runnable?{
private?Resource?resource;
public?Consumer(Resource?resource)?{
this.resource?=?resource;
}
@Override
public?void?run()?{
while?(true)?{
resource.getName();
}
}
}