標籤:
生產者和消費者問題的描述圖
通過,我們可以發現:
生產者和消費者使用的都是同一個資源(肉包子)
所以,當使用線程的時候,這兩類的鎖也是同一把鎖(為了避免出現安全執行緒問題)
例子:學生資訊的錄入和擷取
* 資源類:Student
* 設定學生資料:SetThread(生產者)
* 擷取學生資料:GetThread(消費者)
* 測試類別:StudentDemo
* 資源類:Student
1 public class Student {2 3 String name;4 int age;5 }
* 設定學生資料:SetThread(生產者)
public class SetThread implements Runnable { private int x = 0; // 因為SetThread和Getthread兩個類使用的都是同一個資源 // 所以,在建立一個資來源物件,再通過構造方法傳遞給其它的類 private Student s; public SetThread(Student s) { this.s = s; } public void run() { // 錄入資訊(生產者) while (true) { // 加鎖,且SetThread和Getthread兩個類使用的是同一把鎖,所以鎖的對象是資來源物件s synchronized (s) { if (x % 2 == 0) { s.name = "張三"; s.age = 23; } else { s.name = "李四"; s.age = 24; } x++; } } }}
* 擷取學生資料:GetThread(消費者)
1 public class GetThread implements Runnable { 2 3 private Student s; 4 public GetThread(Student s){ 5 this.s = s; 6 } 7 public void run() { 8 //擷取資訊 消費者 9 //鎖的對象,同SetThread10 while(true){11 synchronized (s){12 System.out.println(s.name +"--" + s.age);13 }14 }15 16 }17 18 }
* 測試類別:StudentDemo
1 public class StudentDemo { 2 3 4 public static void main(String[] args) { 5 6 //建立資來源物件 7 Student s = new Student(); 8 9 //建立錄入和擷取類的對象10 SetThread st = new SetThread(s);11 GetThread gt = new GetThread(s);12 13 //建立線程對象14 Thread t1 = new Thread(st);15 Thread t2 = new Thread(gt);16 17 //啟動線程18 t1.start();19 t2.start();20 21 }22 23 }
結果:
生產者SetThread類不斷地錄入學生資訊(可以看成不斷生產包子?)
而消費者GetThread類則不斷地擷取所錄入的資訊(買包子?)
當然,最理想的狀態是生產者生產1個,消費者就立馬消費1個....
但,這裡還不是這種理想狀態,兩者還是得搶佔CPU的資源,若是生產的多,則就堆積著等消費者。
若是消費者搶佔的資源多,則一直消費的都是同一個包子?。。
java 22 - 16 多線程之生產者和消費者的問題