我的考试有一个问题,由于我不太了解的事情,我没有获得满分。
问题如下:
给定以下程序,应用不允许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;因此无法打印负数?
答案 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);
}
}