Skip to content

Conversation

jbj338033
Copy link
Contributor

The getNullable() method had a subtle race condition where the value field could be read as null after being assigned but before the resolved flag was set to true. This could occur if another thread read the value between lines 136 and 137.

By using a local variable to store the supplier's result and returning that directly, we ensure that the thread that computes the value will always return the correct result, regardless of what other threads observe.

This change maintains the existing behavior documented in the class Javadoc that the supplier may be called multiple times under concurrent access, while fixing the potential for incorrect null returns.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 22, 2025
The getNullable() method had a subtle race condition where the value field
could be read as null after being assigned but before the resolved flag was
set to true. This could occur if another thread read the value between lines
136 and 137.

By using a local variable to store the supplier's result and returning that
directly, we ensure that the thread that computes the value will always
return the correct result, regardless of what other threads observe.

This change maintains the existing behavior documented in the class Javadoc
that the supplier may be called multiple times under concurrent access, while
fixing the potential for incorrect null returns.

Signed-off-by: jbj338033 <jbj338033@gmail.com>
@jbj338033 jbj338033 force-pushed the fix/lazy-race-condition branch from 2a9b094 to ffe1946 Compare September 22, 2025 11:50
@mp911de mp911de self-assigned this Sep 22, 2025
@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 23, 2025
@mp911de mp911de changed the title Fix potential race condition in Lazy.getNullable() Fix potential race condition in Lazy.getNullable() Sep 23, 2025
@mp911de
Copy link
Member

mp911de commented Sep 23, 2025

Thanks a lot, that one is a really hard to spot behavior. How did you find the issue?

@mp911de mp911de closed this in ae29109 Sep 23, 2025
mp911de pushed a commit that referenced this pull request Sep 23, 2025
The getNullable() method had a subtle race condition where the value field
could be read as null after being assigned but before the resolved flag was
set to true. This could occur if another thread read the value between lines
136 and 137.

This change maintains the existing behavior documented in the class Javadoc
that the supplier may be called multiple times under concurrent access, while
fixing the potential for incorrect null returns.

Signed-off-by: jbj338033 <jbj338033@gmail.com>
Closes #3368
mp911de pushed a commit that referenced this pull request Sep 23, 2025
The getNullable() method had a subtle race condition where the value field
could be read as null after being assigned but before the resolved flag was
set to true. This could occur if another thread read the value between lines
136 and 137.

This change maintains the existing behavior documented in the class Javadoc
that the supplier may be called multiple times under concurrent access, while
fixing the potential for incorrect null returns.

Signed-off-by: jbj338033 <jbj338033@gmail.com>
Closes #3368
@mp911de mp911de added this to the 3.4.11 (2024.1.11) milestone Sep 23, 2025
@jbj338033
Copy link
Contributor Author

Thanks a lot, that one is a really hard to spot behavior. How did you find the issue?

I found it while reviewing the codebase files one by one, with some help from AI tools to verify the concurrency issue

@mp911de
Copy link
Member

mp911de commented Sep 23, 2025

Finally, some good usage ❤️ of AI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants