0

This question is more about terminology. I use atomic as a concurrency terminology and I describe it as such : "If multiple threads call the same method concurrently or sequentially, the result will be the same if the method is atomic" Where as I use transactional more like a unit of work terminology. A transactional job is either successful or failed and there will be no intermediate dirty state.

On the other hand, I saw this article and it claims "A method is atomic if it is "all or nothing." If a thread reads the data, the thread can only see the state before or after the execution of the atomic method — no intermediate state. After the atomic method was executed successfully, the changes are visible to all threads. The atomic method only modifies data of its own object without side effects. Here are some examples of atomic methods." It seems to me this definition is not necessarily correct. For instance the below code is atomic but has side effects I think.

    public synchronized void add(){
        x++;
        if(System.currentTimeMillis()%10==0){
            throw new RuntimeException();
        }
        y++;
    }

Is my understanding of the terminology correct?

Fatih Arslan
  • 1,054
  • 1
  • 9
  • 10
  • 1
    What makes you think that that method is atomic? – khelwood May 19 '23 at 08:03
  • `synchronized` just means it takes a lock on `this` object. If you do things to other objects from inside that function, things which other code accesses which *don't* respect the same lock, it's not like an atomic transaction. [Java synchronized method lock on object, or method?](https://stackoverflow.com/q/3047564) – Peter Cordes May 19 '23 at 08:03
  • @khelwood it is atomic because multiple threads can call this method concurrently or sequentially and the result will be the same. Indeed. I just want to copy one part of it. Imagine this is a class with x and y integers. Then it is thread safe and the method is atomic, right? – Fatih Arslan May 19 '23 at 09:04
  • No, it's not atomic because it contains multiple individual operations done separately, so the half-changed state can be visible half way through the method. Not to mention that `x++` isn't even atomic in itself. – khelwood May 19 '23 at 10:30

1 Answers1

2

...I saw this article..."all or nothing"...[another] thread can only see the state before or after the execution

Personally, I disagree with the "all or nothing" part of that description, but I agree with the second part. If thread A performs a truly atomic operation, then any other thread B that shares variables with thread A should only ever be able to see those variables in the state that they were before the operation started, or in the state after thread A completed the operation. Thread B should never be able to see the variables in a half-way-done state.

I think it's the ambiguous "all or nothing" that made you think about transactions.

Your example code throws an exception 10% of the time. If you're using that exception as a model of "failure," and you're expecting that the x++ operation will be "unwound" when a failure occurs, that's not how it's going to work. "Atomic" and "transactional" are related, because the completion of a transaction must happen atomically, but the words mean different things.

If you wanted to guarantee that x and y always receive the same number of increments, even in the face of failure, then until somebody gives us true transactions, you'll have to write explicit code to provide that guarantee:

    public synchronized void add(){
        x++;
        try {
            someOperationThatMightFail();
        }
        catch (Exception e) {
            --x;
            throw e;
        }
        y++;
    }

...the below code is atomic...

It's not really atomic. It could be effectively atomic, but only if no other thread ever accesses the same x and y except when synchronized on the same object. If it were truly atomic, then it would be impossible, under any conditions, for another thread to observe x and y at a moment when the add call was only half-way done. But, if the programmer guarantees that every other thread synchronizes on the same object when accessing those variables, then it has the same effect as if it truly was atomic.

...but it has side effects...

I don't see the "but" in that. Atomicity means nothing unless there are variables shared between the threads. What you're calling "side effects" is how the variables x and y are shared.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57