多執行緒經典消費者例項

2021-07-24 22:42:51 字數 2139 閱讀 6828

需求

我們的程式想要實現這樣的乙個功能,兩個執行緒,乙個不斷往乙個容器加資料,乙個不斷從這個容器取資料。

設計的問題

我們的第乙個問題是,如果容器滿了怎麼辦,空了又怎麼。解決的辦法是使用wait()和notify()。思路是當容器滿或空時,對應的執行緒就應該停下了,等到不空或者不滿的時候再繼續。顯然wait()和notify()可以很好的實現。當空時,暫停取,使用wait(),新增執行緒新增了後就不空了,就可以使用notify()喚醒取的執行緒了。滿的時候也是一樣的。

sleep()和wait()的區別

暫停也可用sleep(),為什麼不用sleep()呢?首先是我們不知道停多久,有notify()配合使用才方便。sleep()和wait()有乙個重要的區別是,sleep()不會讓出物件鎖。我們寫個例子來證明下:

class lock

public synchronized void

sleeptest() catch (interruptedexception e)

}}class print implements runnable

@override

public

void

run()

}class sleeptest implements runnable

@override

public

void

run()

}public

class sleepandwait

}

輸出的結果是,輸出了sleeped 2 second,等待兩秒後,才可以看到輸出的100個thread-1。如果把synchronized去掉,也就是不加鎖,thread-1會立即輸出不會等兩秒。這裡證明sleep是不會讓出物件鎖的。

非常有用的執行緒圖

消費者例項

這是容器,使用乙個類似棧的容器

public

class stack catch (interruptedexception e)

}this.notify();

container[top]=a;

top++;

system.out.println(thread.currentthread().getname()+"入棧的元素"+a);

}public synchronized char

pop() catch (interruptedexception e)

}this.notify();

top--;

system.out.println(thread.currentthread().getname()+"出棧的元素:"+container[top]);

return container[top];}}

生產者

public

class

producer

implements

runnable

@override

public

void

run()}}

消費者

public

class

consumer

implements

runnable

@override

public

void

run() catch (exception e) }}

主線程

public

class threadtest

}

同步的問題

當新增執行緒的push方法和取執行緒的pop方法,不是原子操作時意思就是push方法執行一半,cpu切換給pop方法的執行緒執行,就會出現問題。比如說,當執行了container[top]=a;但是還沒執行top++;切換到取執行緒時,把原來棧頂的元素取出來了並且指標向下減,如果再返回新增執行緒,繼續執行top++;結果就是新新增的元素丟失了,原來棧頂的元素取了一次還在。所以pop方法和push方法要加鎖,作為原子操作。

多執行緒之經典生產者消費者問題

通過訊號量,wait,nofity,synchronized來解決生產者消費者問題。例項如下 package thread public class threadwaitandnotifytest class iphone catch interruptedexception e system.ou...

多執行緒 生產者消費者

這個就不多說了,直接上 include include using namespace std const unsigned short size of buffer 10 緩衝區長度 unsigned short productid 0 產品號 unsigned short consumeid 0...

多執行緒生產消費者模式

package net.jxatei.jsj.thread 消費者與生產者共同的資源 author 安 緹 吖 public class clerk catch interruptedexception e try catch interruptedexception e system.out.pr...