一時および揮発性修飾子とは何ですか?


126

誰かがJavaでtransientand volatile修飾子が何を意味するのか説明できますか?


3
これは明らかに問題ではありませんでしたし、これはとにかく重複しています(そのため、私が投票に投票しました)。たとえば、Javaに一時変数があるのはなぜですか?そして、いつJavaでvolatileキーワードを正確に使用しますか?(および他の多く)。
Pascal Thivent、2010


18
これは、と同等の完全に有効な質問です:stackoverflow.com/questions/215497/...
バリーFruitman

回答:


156

volatileそしてtransient改質剤は、クラスのフィールドに適用することができる1フィールドタイプによらず。それを除いて、それらは無関係です。

transient修飾子は、クラスのインスタンスをシリアル化するとき、フィールドを除外するために、Javaオブジェクトのシリアル化サブシステムに指示します。オブジェクトがデシリアライズされると、フィールドはデフォルト値に初期化されます。つまりnull、参照型の場合、ゼロまたはfalseプリミティブ型の場合です。JLS(8.3.1.3を参照)は何をtransient意味するのかを述べていないが、Java Object Serialization Specificationに従います。他のシリアル化メカニズム、フィールドのtransientネスに注意を払う場合があります。または、彼らはそれを無視するかもしれません。

(JLSではstaticフィールドをとして宣言することが許可されていることに注意してくださいtransient。この組み合わせは、静的オブジェクトをシリアル化しないため、Javaオブジェクトのシリアル化には意味がありません。ただし、他のコンテキストでは意味がある可能性があるため、それを完全に禁じないでください。)

volatile修飾子は、フィールドへの書き込みは、常に同期メモリにフラッシュする必要があり、それは常にメモリから読み出されなければならない分野で読み取るようにJVMに指示します。つまり、揮発性としてマークされたフィールドは、ネイティブまたは標準のライブラリベースの同期を使用せずに、マルチスレッドアプリケーションで安全にアクセスおよび更新できます。同様に、揮発性フィールドへの読み取りと書き込みはアトミックです。(これは>>不揮発<<には適用されないlongか、double一部のJVM上の「単語引き裂き」の対象とすることができる、フィールド。)JLSの要部である8.3.1.417.4及び17.7


1-ただし、ローカル変数またはパラメーターには適用されません。


10

volatiletransientキーワード

1)transientキーワードをインスタンス変数と共に使用して、シリアル化プロセスから除外します。フィールドがtransientその値である場合、永続化されません。

一方、volatileキーワードは、Java変数を「メインメモリに格納されている」としてマークするために使用されます。

volatile変数のすべての読み取りは、CPUキャッシュからではなくコンピューターのメインメモリから読み取られ、volatile変数へのすべての書き込みは、CPUキャッシュだけでなくメインメモリに書き込まれます。

2)transientキーワードは、statickeyword と一緒に使用できませんが、と一緒volatileに使用できますstatic

3)transient変数はデシリアライズ中にデフォルト値で初期化され、値の割り当てまたは復元はアプリケーションコードで処理する必要があります。

詳細については、私のブログを参照してください:http :
//javaexplorer03.blogspot.in/2015/07/difference-between-volatile-and.html


2
理由transient変数が一緒に使用することはできませんstaticキーワードは、クラスにしていない任意の個々のインスタンスに属して静的変数です。シリアル化の概念は、オブジェクトの現在の状態に関係しています。クラスの特定のインスタンスに関連付けられたデータのみがシリアル化されるため、静的メンバーフィールドはシリアル化時に無視されます
Chaklader Asfak Arefe

実際、JLSは許可しstatictransient一緒に使用されます。典型的なシリアル化メカニズムは静的を永続化しないため、問題はほとんど意味がありません。
Stephen C

7

揮発性とは、他のスレッドがその特定の変数を編集できることを意味します。したがって、コンパイラはそれらへのアクセスを許可します。

http://www.javamex.com/tutorials/synchronization_volatile.shtml

一時的とは、オブジェクトをシリアル化すると、逆シリアル化時にデフォルト値が返されることを意味します

http://www.geekinterview.com/question_details/2


5
「したがって、コンパイラはそれらへのアクセスを許可します。」あなたの文は、スレッドにはデフォルトでアクセス権がないことを示唆しています。今、私はリンクと私が理解する他の答えを読みます:コンパイラーは、変数のいかなる種類のスレッド固有の中間ストレージも実行しないので、他のスレッドは変更を即座に見ることができます。
ヘリオス

揮発性のCの使用と揮発性のJavaの使用が混同されました。コンパイラーは、キャッシュされた値ではなく、フィールドの実際の値にアクセスできるようにすることを意味しました。
レイノス2010

それだけではありません。
スティーブンC

1

一時的:

まず、ギャップを埋める方法がどこに必要かを知る必要があります。

1)アクセス修飾子トランジェントは、可変コンポーネントにのみ適用できます。メソッドまたはクラスでは使用されません。

2)一時的なキーワードを静的なキーワードと一緒に使用することはできません。

3)シリアライゼーションとは何ですか?それはどこで使用されますか?シリアライゼーションは、オブジェクトの状態を永続化するプロセスです。これは、オブジェクトの状態がバイトストリームに変換され、永続化(ファイルへのバイトの格納など)または転送(ネットワーク経由でのバイトの送信など)に使用されることを意味します。同様に、逆シリアル化を使用して、オブジェクトの状態をバイトから戻すことができます。シリアライゼーションは主にネットワークプログラミングで使用されるため、これはJavaプログラミングの重要な概念の1つです。ネットワーク経由で送信する必要があるオブジェクトは、バイトに変換する必要があります。一時的なキーワードを理解する前に、シリアル化の概念を理解する必要があります。読者がシリアル化について知っている場合は、最初のポイントをスキップしてください。

注1)Transientは主にシリアル化プロセスに使用されます。そのため、クラスはjava.io.Serializableインターフェースを実装する必要があります。クラスのすべてのフィールドはシリアライズ可能でなければなりません。フィールドがシリアル化可能でない場合は、一時的としてマークする必要があります。

注2)逆シリアル化プロセスが実行されると、それらはデフォルト値に設定されます-タイプの制約に従って、ゼロ、false、またはnull。

注3)一時的なキーワードとその目的?一時的な修飾子で宣言されたフィールドは、シリアル化されたプロセスに参加しません。オブジェクトがシリアル化(任意の状態で保存)されると、その一時フィールドの値はシリアル表現で無視されますが、一時フィールド以外のフィールドはシリアル化プロセスに参加します。これが、transientキーワードの主な目的です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.