(一)生產者消費者問題:安全
1.題目:多線程
採用Java 多線程技術,設計實現一個符合生產者和消費者問題的程序。 對一個對象(槍膛)進行操做,其最大容量是10顆子彈。 生產者線程是一個壓入線程,它不斷向槍膛中壓入子彈;消費者線程是一個射出線程,它不斷從槍膛中射出子彈。ide
2.分析:函數
這是個生產者與消費者問題,也是線程的同步問題, 爲了防止執行個線程訪問一個資源時出現忙等待,要使用的wait-notify函數,是兩個線程交替執行。測試
3.解題步驟:this
a.建立一個Factory類,包含Produce()方法和Consume()方法; spa
b.建立一個Producer線程,模擬生產子彈; 線程
c.建立一個Consume線程,模擬消費子彈 ;設計
d.建立一個測試類Demo.3d
4.畫圖理解:
5.擴展 - 線程安全問題
(1)線程安全出現的緣由:
a.多線程的環境下;(單線程不會出現安全問題)
b.多個線程擁有資源;
c.對共享資源的操做不是原子性的。(原子性是指一次操做要麼執行完,要麼不執行)
(2)那麼怎麼解決線程安全問題呢?
答:使用同步代碼塊。
格式:
sychronized (對象) {
要同步的代碼塊(你走我不走,我走你不走)
}
(二)代碼體現:
1.建立一個Factory類
public class Factory { String name;//加工廠名字 int MAX_SIZE;//最多加工子彈數目 int size;//當前剩餘子彈數 public Factory(String name, int MAX_SIZE) { this.name = name; this.MAX_SIZE = MAX_SIZE; } //使用同步方法,保證線程安全 public synchronized void produce(){ while (size >= MAX_SIZE){ try { //子彈充足,等待消費 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { //加工子彈累了,休息會 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //生產了一顆子彈 size++; System.out.println("壓入了一顆子彈,還剩下" + size + "顆"); //喚醒等待的全部線程 notifyAll(); } //使用同步方法,保證線程安全 public synchronized void consume(){ while (size <= 0){ try { //沒有子彈了,等待 wait(); } catch (InterruptedException e) { e.printStackTrace(); } try { Thread.sleep(200);//射出子彈累了,休息會 } catch (InterruptedException e) { e.printStackTrace(); } } //射出了一顆子彈 size--; System.out.println("射出了一顆子彈,還剩下" + size + "顆"); //喚醒等待的全部線程 notifyAll(); } }
2.建立一個Producer類實現Runnable接口
public class Producer implements Runnable { Factory factory; public Producer(Factory factory) { this.factory = factory; } @Override public void run() { //循環生產 while (true){ factory.produce(); } } }
3.建立一個Consume類實現Runnable接口
public class Consumer implements Runnable{ Factory factory; public Consumer(Factory factory) { this.factory = factory; } @Override public void run() { //循環消費 while (true){ factory.consume(); } } }
4.建立一個測試類Demo
public class Demo { public static void main(String[] args) { //建立一個加工廠 Factory factory = new Factory("子彈加工廠",200); //建立一個生產者對象和一個消費者對象 Producer producer = new Producer(factory); Consumer consumer = new Consumer(factory); //建立一個生產者線程和一個消費者線程 Thread t1 = new Thread(producer); Thread t2 = new Thread(consumer); //啓動線程 t1.start(); t2.start(); } }