java多线程synchronized同步的问题

2025-05-19 16:22:13
推荐回答(3个)
回答1:

首先我确认一下你的需求,你实际上是想做这件事

有4个线程,两个负责售货,两个负责进货,其中售货速度3>进货速度1,默认当前库存为100,然后4个线程启动,在你的期望中库存只要大于2,就可以出货,库存小于200就要进货

下面是我对上面的需求做的一点小修改,不知道符合你的要求么?

jinhuo.java

class jinhuo {
    private huowu h;
    boolean flag = true;

    public void jin(huowu h) {
        this.h = h;
    }

    public  void show() {
        while (flag) {
            synchronized(h){
                if (h.com <200){
                    shixian();
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void shixian() {
        h.com++;
        System.out.println(Thread
            .currentThread()
            .toString() + "-------补货完成,当前库存剩余" + h.com);
    }
}

shouhuo.java


class shouhuo {
    private huowu h;
    boolean flag = true;

    public void jin(huowu h) {
        this.h = h;
    }

    public void show() {
        while (flag) {
            synchronized (h) {
                if (h.com > 2){
                    shixian();
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void shixian() {
        h.com = h.com - 3;
        System.out.println(Thread
            .currentThread()
            .toString() + "-------售货完成,当前库存剩余" + h.com);
    }
}

其余代码不变

部分打印结果,这个临界值部分

Thread[Thread-1,5,main]-------售货完成,当前库存剩余3
Thread[Thread-0,5,main]-------售货完成,当前库存剩余0
Thread[Thread-2,5,main]-------补货完成,当前库存剩余1
Thread[Thread-3,5,main]-------补货完成,当前库存剩余2
Thread[Thread-3,5,main]-------补货完成,当前库存剩余3
Thread[Thread-2,5,main]-------补货完成,当前库存剩余4
Thread[Thread-0,5,main]-------售货完成,当前库存剩余1
Thread[Thread-2,5,main]-------补货完成,当前库存剩余2
Thread[Thread-3,5,main]-------补货完成,当前库存剩余3

=============================================================

至于你代码中的问题

  1. 终止循环的flag是不必要的,不要终止线程会使你的这个需求看上去更加的合理

  2. 我加了点线程的阻塞时间,以免执行太快无法很好的展现结果

  3. 同步标志你原来是加在方法上了,我改在了对象上

  4. 既然是面向对象的编程,为什么传入线程的是对象的某个属性而不是对象本身呢..

回答2:

uqortbsa正解,不过需稍微改动一下
类静态变量声明
private static int[] globalA = new int[100];
private static int[] globalB = new int[100];
key方法开始这样:
if (false) {
int a[] = new int[100];
int b[] = new int[100];
}
int a[] = globalA;
int b[] = globalB;

回答3:

能够告诉你想要干什么么?