记录在经典多线程例子生产者消费者模型中出的错

一开始我选用的是自己当时较为顺手的实现Runnable的做法来做这道题,利用继承来获取共享数据,结果陷入死锁,百思不得其解。反复审阅代码发现,这样做,生产者和消费者类始终共用的同一共同数据,造成死锁。

package Java2;

class barn {
    static int product = 0;
}

class Productor extends barn implements Runnable {
    @Override
    public void run() {
        synchronized (this) {
            while (true) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (product < 20) {
                    product++;
                    System.out.println(Thread.currentThread().getName() + "生产了第" + product + "件商品");
                    notify();
                } else {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}


class Customer extends barn implements Runnable {
    @Override
    public void run() {
        synchronized (this) {
            while (true) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (product > 0) {
                    System.out.println(Thread.currentThread().getName() + "消费了第" + product + "件商品");
                    product--;
                    notify();
                } else {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

public class Classic {
    public static void main(String[] args) {

        Productor p = new Productor();
        Customer cu = new Customer();
        Thread x = new Thread(p);x.setName("生产者:");
        Thread y = new Thread(cu);y.setName("消费者:");

        x.start();
        y.start();

    }
}


最后,使用了同步方法+继承Thread来解这道题。将具体功能都封装成同步方法,然后让消费者和生产者类来实例化并调用(implements Runnable貌似不支持类中再去带参构造所以才换的继承Thread)。

package Java2;

class Barn {
    private int product = 0;

    public synchronized void produceProduct() {
        if (product < 20) {
            product++;
            System.out.println(Thread.currentThread().getName() + "生产了第" + product + "件商品");
            notify();
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public synchronized void consumeProduct() {
        if (product > 0) {
            System.out.println(Thread.currentThread().getName() + "消费了第" + product + "件商品");
            product--;
            notify();
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Productor extends Thread{
    private Barn barn;

    public Productor(Barn barn) {
        this.barn = barn;
    }


    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            barn.produceProduct();
        }
    }
}


class Customer extends Thread {
    private Barn barn;
    Customer(Barn barn){
        this.barn = barn;
    }
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            barn.consumeProduct();
        }
    }
}

public class Classic {
    public static void main(String[] args) {
        Barn b = new Barn();
        Productor p = new Productor(b);        p.setName("生产者:");

        Customer cu = new Customer(b);        cu.setName("消费者:");
        
        p.start();
        cu.start();

    }
}


小结:在多线程当中,确定好共享数据真的非常重要。如果没有给线程分工明确地去调用共享数据,一不留神就会造成死锁。
posted @   ice_yolo  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示