Java 线程同时递增和递减 int

标签 java multithreading thread-safety synchronization

因为这是我在 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/

相关文章:

c# - 安全地附加到 Parallel.ForEach 中的列表

java - 在java中解析XML文件的元数据属性

java - Axis2 空数组

java - 套接字接受和多线程

java - 在线程内使用 for 循环与类似的 while 循环行为不匹配

c++ - 共享指针线程安全是零成本吗?

django - django 的 ORM 线程安全吗?

java - 在 Java 中将拉丁字符转换为普通文本

java - 在对象数组中 = 所有元素都相同......分配数据后

c++ - 如何使用带线程的 Google 测试