Movatterモバイル変換


[0]ホーム

URL:


CodeQL documentation
CodeQL resources

Safe publication

ID: java/safe-publicationKind: problemSecurity severity: Severity: warningPrecision: highTags:   - quality   - reliability   - concurrencyQuery suites:   - java-code-quality.qls

Click to see the query in the CodeQL repository

In a thread-safe class, values must be published safely to avoid inconsistent or unexpected behavior caused by visibility issues between threads. If a value is not safely published, one thread may see a stale or partially constructed value written by another thread, leading to subtle concurrency bugs.

In particular, values of primitive types should not be initialised to anything but their default values (which forObject isnull) unless this happens in a static context.

Techniques for safe publication include:

  • Using synchronized blocks or methods to ensure that a value is fully constructed before it is published.

  • Using volatile fields to ensure visibility of changes across threads.

  • Using thread-safe collections or classes that provide built-in synchronization, such as are found injava.util.concurrent.

  • Using thefinal keyword to ensure that a reference to an object is safely published when the object is constructed.

Recommendation

Choose a safe publication technique that fits your use case. If the value only needs to be written once, say for a singleton, consider using thefinal keyword. If the value is mutable and needs to be shared across threads, consider using synchronized blocks or methods, or using a thread-safe collection fromjava.util.concurrent.

Example

In the following example, the values ofvalue andserver_id are not safely published. The constructor creates a new object and assigns it to the fieldvalue. However, the field is not declared asvolatile orfinal, and there are no synchronization mechanisms in place to ensure that the value is fully constructed before it is published. A different thread may see the default valuenull. Similarly, the fieldserver_id may be observed to be0.

publicclassUnsafePublication{privateObjectvalue;privateintserver_id;publicUnsafePublication(){value=newObject();// Not safely published, other threads may see the default value nullserver_id=1;// Not safely published, other threads may see the default value 0}publicObjectgetValue(){returnvalue;}publicintgetServerId(){returnserver_id;}}

To fix this example, we declare the fieldvalue as volatile. This will ensure that all changes to the field are visible to all threads. The fieldserver_id is only meant to be written once, so we only need the write inside the constructor to be visible to other threads; declaring itfinal guarantees this:

publicclassSafePublication{privatevolatileObjectvalue;privatefinalintserver_id;publicSafePublication(){value=newObject();// Safely published as volatileserver_id=1;// Safely published as final}publicsynchronizedObjectgetValue(){returnvalue;}publicintgetServerId(){returnserver_id;}}

References


[8]ページ先頭

©2009-2025 Movatter.jp