線程同步——生產者消費者

瞭解完線程交互和線程同步後,寫下來看一個綜合的例子——生產者消費者java

//生產者
public class Producer extends Thread {
    private int neednum;
    private Godown godown;

    Producer(int neednum, Godown godown){
        this.neednum = neednum;
        this.godown = godown;
    }

    @Override
    public void run() {
        godown.produce(neednum);
    }
}

//消費者
public class Consumer extends Thread {
    private int neednum;
    private Godown godown;

    Consumer(int neednum, Godown godown){
        this.neednum = neednum;
        this.godown = godown;
    }

    @Override
    public void run() {
        godown.consume(neednum);
    }
}

//倉庫
public class Godown {
    public static final int max_size = 100;
    public int curnum;

    public static void main(String[] args) {
        Godown godown = new Godown(30);
        Consumer c1 = new Consumer(50, godown);
        Consumer c2 = new Consumer(20, godown);
        Consumer c3 = new Consumer(30, godown);
        Producer p1 = new Producer(10, godown);
        Producer p2 = new Producer(10, godown);
        Producer p3 = new Producer(10, godown);
        Producer p4 = new Producer(10, godown);
        Producer p5 = new Producer(10, godown);
        Producer p6 = new Producer(10, godown);
        Producer p7 = new Producer(80, godown);
        c1.start();
        c2.start();
        c3.start();
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
        p6.start();
        p7.start();
    }

    Godown() {
    }

    Godown(int curnum) {
        this.curnum = curnum;
    }

    /**
     * 生產指定數量的產品
     */
    public synchronized void produce(int neednum) {
        while (neednum + curnum >= max_size) {
            System.out.println("要生產的產品數量" + neednum + "超過剩餘庫存量" + (max_size - curnum) + " 暫時不能執行生產任務 !");
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //知足生產條件,則進行生產
        curnum += neednum;
        System.out.println("已經生產了" + neednum + "個產品,現倉儲量爲" + curnum);
        notifyAll();
    }

    /**
     * 消費指定數量的產品
     */
    public synchronized void consume(int neednum) {
        while (curnum < neednum) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        curnum -= neednum;
        System.out.println("已經消費了" + neednum + "個產品,現倉儲量爲" + curnum);
        notifyAll();

    }
}
//結果
已經消費了20個產品,現倉儲量爲10
已經生產了10個產品,現倉儲量爲20
已經生產了10個產品,現倉儲量爲30
已經消費了30個產品,現倉儲量爲0
已經生產了10個產品,現倉儲量爲10
已經生產了10個產品,現倉儲量爲20
已經生產了10個產品,現倉儲量爲30
已經生產了10個產品,現倉儲量爲40
要生產的產品數量80超過剩餘庫存量60 暫時不能執行生產任務 !

例子參考:http://lavasoft.blog.51cto.com/62575/221932ide

上面的例子使用同步方法實現的,下面咱們使用同步代碼塊實現。this

public class Producer extends Thread {
    private int neednum;
    private Godown godown;

    Producer(int neednum, Godown godown) {
        this.neednum = neednum;
        this.godown = godown;
    }

    @Override
    public void run() {
        synchronized (this) {
            while (neednum + godown.getCurnum() >= Godown.max_size) {
                System.out.println("要生產的產品數量" + neednum + "超過剩餘庫存量" + (Godown.max_size - godown.getCurnum()) + " 暫時不能執行生產任務 !");
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //知足生產條件,則進行生產
            godown.setCurnum(godown.getCurnum() + neednum);
            System.out.println("已經生產了" + neednum + "個產品,現倉儲量爲" + godown.getCurnum());
            notifyAll();
        }

    }
}

public class Consumer extends Thread {
    private int neednum;
    private Godown godown;

    Consumer(int neednum, Godown godown){
        this.neednum = neednum;
        this.godown = godown;
    }

    @Override
    public void run() {
        synchronized (this){
            while (godown.getCurnum() < neednum) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            godown.setCurnum(godown.getCurnum() - neednum);
            System.out.println("已經消費了" + neednum + "個產品,現倉儲量爲" + godown.getCurnum());
            notifyAll();
        }
    }
}

public class Godown {
    public static final int max_size = 100;
    public int curnum;

    public int getCurnum() {
        return curnum;
    }

    public void setCurnum(int curnum) {
        this.curnum = curnum;
    }

    public static void main(String[] args) {
        Godown godown = new Godown(30);
        Consumer c1 = new Consumer(50, godown);
        Consumer c2 = new Consumer(20, godown);
        Consumer c3 = new Consumer(30, godown);
        Producer p1 = new Producer(10, godown);
        Producer p2 = new Producer(10, godown);
        Producer p3 = new Producer(10, godown);
        Producer p4 = new Producer(10, godown);
        Producer p5 = new Producer(10, godown);
        Producer p6 = new Producer(10, godown);
        Producer p7 = new Producer(80, godown);
        c1.start();
        c2.start();
        c3.start();
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
        p6.start();
        p7.start();
    }

    Godown(int curnum) {
        this.curnum = curnum;
    }
}
相關文章
相關標籤/搜索