生产者消费者类似的线程问题,线程不能正常停止

前两天做java作业,碰到这样一道题目:

准备两个线程对象,启动之后,每个线程执行3次之后再由下一个线程继续执行3次。

线程1执行1次
线程1执行2次
线程1执行3次
线程2执行1次
线程2执行2次
线程2执行3次
-----------------
线程1执行1次
线程1执行2次
线程1执行3次
线程2执行1次
线程2执行2次
线程2执行3次
----------------
线程1执行1次
线程1执行2次
线程1执行3次
线程2执行1次
线程2执行2次
线程2执行3次
。。。。。。

 然后以下是我对应的程序代码:

public class Work {
    private int num;
    private int temp;//切换线程

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public int getTemp() {
        return temp;
    }

    public void setTemp(int temp) {
        this.temp = temp;
    }

    public synchronized void working1(){
        String name=Thread.currentThread().getName();
        try{
            if (num < 3){
                for (int i=0;i<3;i++){
                    num++;
                    System.out.println(name+"执行"+num+"次");
                }
                if (num==3){
                    this.notifyAll();
                }
            }else if (num==3){
                num=0;
                this.wait();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
public class ThreadA implements Runnable{

    private Work work;

    public ThreadA(Work work){
        this.work=work;
    }

    @Override
    public void run() {
        for (int i=0;i<9;i++){
            work.working1();
        }
    }
}
public class Ex2 {
    public static void main(String[] args) {
        Work work=new Work();
        work.setNum(0);
        work.setTemp(0);
        Thread a=new Thread(new ThreadA(work),"线程1");
        a.start();
        Thread b=new Thread(new ThreadA(work),"线程2");
        b.start();
    }
}

但是在程序运行之后,发现“线程1”和“线程2”并不能正常结束

 但是输出结果是正确的

经过调试发现应该是两个线程在执行过程中都被wait()所导致的。

            if (num < 3){
                for (int i=0;i<3;i++){
                    num++;
                    System.out.println(name+"执行"+num+"次");
                }
                if (num==3){
                    this.notifyAll();
                }
            }else if (num==3){
                num=0;
                this.wait();
            }

每当num==3时,当前线程就会进入wait()状态。因为else if(num==3)进入时,导致notifyALL()无法执行,所以两条线程都会wait(),导致子线程无法结束,程序无法结束

修改为:

                if (num==3){
//                    this.notifyAll();
                    this.wait();
                }
            }else if (num==3){
                num=0;
//                this.wait();
                this.notifyAll();

 问题解决。

但是其实这个程序还是有问题的。

在生产者消费者问题中,正确的流程应该是:

线程A生产 > 生产完成 > 通知线程B > 线程A进入wait > 线程B开始消费 > 消费完成 > 通知线程A开始生产 > 线程B进入wait > 线程A开始生产

以这样的一个方式开始循环。

但再这个程序中,流程是不规范的:

线程A执行 > 线程A执行 > 线程A开始沉睡 > 通知其他所有线程开始 > 线程B和线程A开始 > 线程A等待线程B结束 ........

也就是说,线程B还没接说,线程A就还是醒了,但是因为线程B加了锁,所以A要等待B执行,效果虽然能达到,但是当线程多了以后,比如多了一个C线程,很可能会造成A和C的争抢,导致程序出现bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值