开发者社区> 问答> 正文

Java 基础部分的高级编程中的多线程综合案例,数字加减的多线程同步异常

当只有两个线程的时候,程序加减交替执行,运行正常,当有四个线程的时候,程序可能出现连加连减的情况。请帮忙看看问题出在哪里。详细代码如下:

public class NumDemo {
    public static void main(String[] args) {
        Resource res = new Resource();
        Runnable ars =new AddThread(res);
        Runnable srs = new SubThread(res);
        new Thread(ars,"加法A").start();
        new Thread(ars,"加法B").start();
        new Thread(srs,"减法X").start();
        new Thread(srs,"减法Y").start();
    }
}

class Resource{
    private int num =0 ;
    //定义执行数字加减的标记,当flag = true时,执行加法,否则执行减法
    private  boolean flag = true;
    public   void add() {
        synchronized (this){
            if(!this.flag){
                System.out.println(Thread.currentThread()
                        .getName()
                        +" 等待中" +this.flag);
                try {
                    super.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //执行完成加法以后,将flag标记设置为false,
            this.flag=false;
            this.num++;
            System.out.println(Thread.currentThread()
                    .getName()
                    +" current number =" +this.num+" "+this.flag);


            super.notifyAll();//唤醒其他等待的线程
        }
    }
    public void sub(){
        synchronized (this){
            if(this.flag==true){
                System.out.println(Thread.currentThread()
                        .getName()
                        +" 等待中" +this.flag);
                try {
                    super.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.flag=true;
            this.num--;
            System.out.println(Thread.currentThread()
                    .getName()
                    +" current number =" +this.num +" "+this.flag);
            super.notifyAll();
        }

    }
}
class AddThread implements Runnable{
    private Resource res;
    public AddThread(Resource res){
        this.res = res;
    }

    @Override
    public void run() {
        for(int i=0;i<50;i++){
            try {
                this.res.add();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
class SubThread implements Runnable{
    private Resource res;
    public SubThread(Resource res){
        this.res = res;
    }

    @Override
    public void run() {
        for(int i=0;i<50;i++){
            try {
                this.res.sub();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

展开
收起
游客pi4pgwoeddkl6 2021-03-14 22:12:26 619 0
1 条回答
写回答
取消 提交回答
  • 出现问题的原因为:Thread.sleep()会发生切换,因此需要再执行更新操作时,重新判定标记是否已经更新。

    2021-04-08 18:24:11
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载