因为这是我在 stackoverflow 上遇到的第一个问题,所以我会尽力解释它。
如果这是一个重复的问题,我很抱歉,但我花了很多时间搜索,但找不到答案。 自从我不久前开始学习线程以来,我现在遇到了一个障碍:D 我想编写一个非线程安全的方法,使用两个线程同时递增和递减一个整数。
所以到目前为止我的代码是这样的..遗憾的是不起作用,我不知道为什么
public class ThreadFunctions {
private int counter = 0;
private boolean command = false;
public synchronized void changeNumber(boolean command){
this.command = command;
synchronized (this) {
if(command){
counter++;
}else{
counter--;
}
}
}
public synchronized int getCounter(){
return this.counter;
}
}
这就是我用来测试它的类。
public class Demo{
public static void main(String[] args){
final ThreadFunctions o = new ThreadFunctions();
new Thread(new Runnable() {
@Override
public void run() {
while(o.getCounter() < 100){
o.changeNumber(true);
System.out.println("Thread: " + Thread.currentThread().getId() + " counter: "+o.getCounter());
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(o.getCounter() > -100){
o.changeNumber(false);
System.out.println("Thread: " + Thread.currentThread().getId() + " counter: "+ o.getCounter());
}
}
}).start();
}
}
结果是这样的......
Thread: 10 counter: 5
Thread: 10 counter: 6
Thread: 10 counter: 7
Thread: 10 counter: 8
Thread: 10 counter: 9
Thread: 11 counter: 8
Thread: 10 counter: 9
Thread: 10 counter: 10
Thread: 10 counter: 11
Thread: 10 counter: 11
Thread: 10 counter: 12
Thread: 10 counter: 13
Thread: 11 counter: 13
etc..
正如你所看到的,线程仍然没有同步,我不明白为什么:(
最佳答案
为了确保递增/递减操作的原子性,您可以使用 AtomicInteger
代替。
在您的情况下,为了确保原子性,而不是递增
/递减
,然后获取
未按原样原子完成的值不在同一个同步块(synchronized block)中完成,您应该只使用一种方法来完成这两项操作,如下所示:
public synchronized int changeNumber(boolean command){
this.command = command;
if (command){
counter++;
} else {
counter--;
}
return counter;
}
那么线程执行的代码将是:
while(o.getCounter() < 100) {
System.out.println(
"Thread: " + Thread.currentThread().getId() + " counter: " + o.changeNumber(true)
);
}
和
while(o.getCounter() > -100) {
System.out.println(
"Thread: " + Thread.currentThread().getId() + " counter: " + o.changeNumber(false)
);
}
关于Java 线程同时递增和递减 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36985127/