Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaのvolatileとtransientキーワードの違いを徹底解説

Javaには、それぞれ異なる目的で使われるvolatiletransientという2つの修飾子があります。名前は似ていますが、役割はまったく別物です。この記事では、両者の違いをわかりやすく解説します。

volatileキーワードとは

volatileは、主にマルチスレッド環境で使用されるキーワードです。複数のスレッドが同じ変数に対して同時に読み書きを行う場合、通常はCPUキャッシュに値が保持されるため、スレッド間で値の不整合が発生する可能性があります。volatileを付けた変数は、変更内容がCPUキャッシュを経由せずメインメモリに直接反映されるため、すべてのスレッドが常に最新の値を読み取ることができます。

transientキーワードとは

一方、transientシリアライズ(直列化)の際に使用されるキーワードです。transientが付いたフィールドは、シリアライズおよびデシリアライズの対象から除外されます。パスワードなど、保存したくない機密情報や、シリアライズする意味のない値を持つ変数に対して指定します。

volatileとtransientの比較表

#項目volatiletransient
1基本変更内容をメインメモリに直接書き込むために使用するシリアライズ時に変数を除外するために使用する
2デフォルト値デフォルト値で初期化されないデシリアライズ時、transient変数はデフォルト値で初期化される
3staticとの併用static変数と組み合わせて使用できるstaticキーワードと組み合わせて使用できない
4finalとの併用finalキーワードと組み合わせて使用できるfinalキーワードと組み合わせて使用できない

transientの使用例

// transientキーワードを使って、
// 特定フィールドのシリアライズをスキップするサンプルクラス
class TransientExample implements Serializable {
    transient int age; // シリアライズ対象外
    private String name;
    private String address;
    // その他のコード
}

volatileの使用例

class VolatileExample extends Thread {
    volatile boolean isRunning = true;
    public void run() {
        long count = 0;
        while (isRunning) {
            count++;
        }
        System.out.println("Thread terminated." + count);
    }
    public static void main(String[] args) throws InterruptedException {
        VolatileExample t = new VolatileExample();
        t.start();
        Thread.sleep(2000);
        t.isRunning = false;
        t.join();
        System.out.println("isRunning set to " + t.isRunning);
    }
}

上記の例では、isRunningフラグがvolatileとして宣言されているため、メインスレッドがfalseに設定した変更が即座に実行中のスレッドに反映され、ループが確実に終了します。

まとめ

  • volatile: マルチスレッド環境における変数の可視性を保証し、変更をメインメモリに直接反映させる。
  • transient: シリアライズの対象から特定のフィールドを除外するために使用する。

用途がまったく異なるため、状況に応じて適切なキーワードを選択することが重要です。

  1. JavaのIteratorとEnumerationの違いを徹底比較!使い分けのポイントを解説

    はじめに:IteratorとEnumerationとはJavaのコレクションフレームワークには、コレクション内の要素を順番に走査(トラバース)しながらアクセスするための仕組みとして「カーソル」が用意されています。その代表格が Iterator(イテレータ) と Enumeration(列挙) の2つです。両者はどちらもコレクションフレームワークに属しますが、登場した時期と役割が異なります。EnumerationはJDK 1.0から存在する歴史あるインターフェースで、IteratorはJDK 1.2でコレクションフレームワークとともに導入された、より新しいインターフェースです。Enumerati

  2. JavaでのArrayListとHashSetの違いを徹底解説!使い分けのポイントも紹介

    HashSetとArrayListは、どちらもJavaコレクションフレームワークにおいて最も重要なクラスの一つです。それぞれ特徴が異なるため、用途に応じた適切な使い分けが求められます。本記事では、ArrayListとHashSetの主な違いを6つの観点から比較し、実際のサンプルコードとともにわかりやすく解説します。ArrayListとHashSetの違い一覧No.項目ArrayListHashSet1実装インターフェースListインターフェースを実装しています。Setインターフェースを実装しています。2内部構造内部的には配列(動的配列)を使って実装されています。内部的にはHashMapを使って