生產者和消費者代碼實現
阿新 • • 發佈:2019-05-08
同步方法 當前 try 今天 run 內部 消費者 pre 經典
一直對wait和notify的了解停留在理論階段,所以通過一個經典的生產者和消費者案例感受下線程的同步。下面對涉及到的生產者、消費者的對象進行介紹。
先來實現下消費者的代碼:
class Consumer extends Thread
{
private ProducterAndConsumer producterAndConsumer;
public Consumer(ProducterAndConsumer producterAndConsumer)
{
this.producterAndConsumer = producterAndConsumer;}
public void run()
{
while(true)
{
producterAndConsumer.consuem();
}
}
}
代碼已經相當簡潔了,就是線程循環執行消費方法,成員變量ProducterAndConsumer類是個測試類,這個類稍後介紹,接著實現生產者的代碼。
class Producter extends Thread
{
private ProducterAndConsumer producterAndConsumer;
public Producter(ProducterAndConsumer producterAndConsumer){
this.producterAndConsumer = producterAndConsumer;
}
public void run()
{
while(true)
{
producterAndConsumer.product();
}
}
}
同樣的,生產者循環執行生產方法,接著介紹主類,就是ProducterAndConsumer類。
public class ProducterAndConsumer {
public volatile int num = 0;
public synchronized void product(){
if(num < 100)
{
System.out.println("開始生產:"+num+"*************************************");
++num;
notify();
}
else
{
System.out.println("貨量充足,放心消費....................");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
// notify();
}
}
public synchronized void consuem()
{
if(num < 1)
{
try {
System.out.println("貨量不足,請生產");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else
{
System.out.println("開始消費:"+num);
num--;
notify();
}
}
public static void main(String[] args)
{
ProducterAndConsumer producterAndConsumer = new ProducterAndConsumer();
Producter prodocter = new Producter(producterAndConsumer);
Consumer consumer = new Consumer(producterAndConsumer);
prodocter.start();
consumer.start();
}
}
在main方法中,開啟消費者和生產者線程。因為生產者和消費者用的是同一個對象的不同synchronized方法,所以兩個線程會產生producterAndConsumer 對象鎖的競爭,主要是對實例變量num的競爭,其實num前面修飾符volatile不需要,可以去掉,並不會對資源造成影響,因為線程進入同步方法前會去主存重新獲取num的值存到線程內存中,出同步方法前會把自己線程內部存儲的num再刷新到主存中。
現在回到生產者和消費者的線程同步過程中:
假設生產者首先獲得了同步鎖,它先判斷當前num值是否小於100,是的話就說明沒有到預定最大生產量,可以繼續生產,對num加1操作,並喚醒消費者線程(消費者線程會出現num<1,執行wait方法,釋放鎖,在鎖池等待的狀態)來消費,此時兩個線程交替執行。若是執行中,發現num已經到100,就交出鎖,進入鎖等待狀態,把執行權交給消費者線程,等待消費者將它喚醒。
消費者判斷num值>num,所以此刻開始-1操作,並喚醒生產者線程繼續生產,當消費者線程遇到num<1,即此刻的nun=0的情況下,立即交出鎖,暫停執行,等待生產者生產完畢,喚醒它,此時此刻,跟剛才描述的生產者線程工作形成閉環,於是它們倆就相安無事的一直執行下去。今天的內容就介紹到這裏。
生產者和消費者代碼實現