在同步方法中等待vs sleep

时间:2016-02-21 10:50:01

标签: java multithreading

我的考试有一个问题,由于我不太了解的事情,我没有获得满分。

问题如下: 给定以下程序,应用不允许sum打印为负数的更改。

public class Summer {

    private int sum;

    public void up() {
       sum++;
       System.out.println(sum);
    }

    public void down() {
       sum--;
       System.out.println(sum);
    }
}

我所做的更改如下:

public class Summer {

    private volatile int sum;

    public synchronized void up() {
       sum++;
       System.out.println(sum);
    }

    public synchronized void down() {
       while (sum <= 0) {
           try {
                Thread.sleep(100);
           } catch (InterruptedException e) { } 
       }
       sum--;
       System.out.println(sum);
    }
}

我得到的答案是我不能在这个程序中使用sleep,我必须使用wait,我必须使用函数notifyAll来唤醒线程。

我的问题是,为什么我写错了?不应该挥发不允许总和被缓存,因此我总是得到总和的更新版本,因为没有可能的方式我得到一个&#34;脏副本&#34;因此无法打印负数?

2 个答案:

答案 0 :(得分:2)

Sleep方法将睡眠方法置于特定时间,而wait方法执行线程执行直到有人醒来它。 因此,你的while循环将使你的线程无限循环。因此,在down()中使用wait()而不是sleep(...),在up方法中使用notify或notifyAll(),当它递增时使用awake down方法,并且yes indees volatile 变量为每个线程提供新值

答案 1 :(得分:1)

您的方法已同步。如果调用down()sum<= 0,则会无限循环。由于同步方法在this上同步,因此没有其他线程可以从其循环中输入up()以释放down()

至于解决方案,我认为这应该可以解决问题:

public class Summer {

    private volatile int sum;

    public synchronized void up() {
        sum++;
        System.out.println(sum);
        this.notify(); // notify waiting threads that sum has changed
    }

    public synchronized void down() {
        while (sum <= 0) {
            try {
                this.wait(); // wait while sum <= 0. It is not sufficient to
                             // receive a notification and proceed since
                             // multiple threads may call down(). Also, the
                             // thread may wake up due to an interrupt, so
                             // it is advised putting wait() in a loop.
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        sum--;
        System.out.println(sum);
    }
}