Java の Volatile は、オブジェクトに複数のスレッドから同時にアクセスしたい場合にこのキーワードを使用できるように機能します。このキーワードは、クラス、コード、メソッドをスレッドセーフにするもう 1 つの方法であり、複数のスレッドが問題なく同じリソースにアクセスできることを意味します。つまり、キーワードに違反すると、複数のスレッドがその変数値を同時に操作すると言えることになります。
無料ソフトウェア開発コースを始めましょう
Web 開発、プログラミング言語、ソフトウェア テスト、その他
コードをスレッドセーフにしたい場合は、violes キーワードを使用できます。また、同期も提供します。この場合、それは良い選択です。
このキーワードを使用して宣言している変数はキャッシュされません。読み取りや書き込みなど、実行するすべての操作はメイン メモリに保存されます。
class DemoSharedObject { static int sharedresources = 10; }
データの不整合につながる 1 つのケースを以下に示します:
DemoSharedObject という名前のクラスが 1 つあり、複数のスレッドがこのクラスで動作し、クラス メンバーの値を変更すると仮定します。したがって、異なるプロセッサ上で複数のスレッドが実行されている場合、各スレッドは独自のローカル コピー リソースを持ちます。そのため、一部のスレッドが共通リソースの値を変更した場合、その値はメイン メモリにすぐには反映されません。ただし、この場合、他のスレッドは共有リソースの現在の値を知らないため、データの不整合の問題が発生します。
Java には、同期ステートメントと同期メソッドという 2 つのものがあります。
この場合、synchronized キーワードをメソッド シグネチャに追加するだけです。
構文:
public synchronized return_type method_name(){}
例:
public class Demosynchronized { private int c = 0; public synchronized void method1() { c++; } public synchronized void method2() { c--; } public synchronized int method3() { return c; } }
上記の例では、カウンターを増減するだけですが、データの不整合がなく、すべてのスレッドが更新された値を受け取るように、メソッドに同期キーワードを導入する必要があります。
そのため、最初のスレッドが method1() で処理を実行しているとき、他のすべてのスレッドはブロック (一時停止) を取得します。作業スレッドがオブジェクトのロックを取得するまで、他のスレッドは同じオブジェクトにアクセスできません。これにより、データの不整合が回避されます。
また、スレッドがメソッド 1() での操作を完了するたびに、つまりメソッドの実行が完了するたびに、他のスレッドとの関係が確立され、オブジェクトの値や状態の変化が見えるようになります。他のスレッドにも。
構文:
synchronized(){}
例:
public void demo(String namestr) { synchronized(this) { lastName = namestr; count++; } list.add(namestr); }
上記の例では、データを管理する同期ブロックがあります。 namestr と同様に、demo() メソッドによって同期されます。これは、同期したいデータを意味します。それらをこのブロックにのみ配置する必要があるだけです。
同じオブジェクトに対して書き込みと読み取りを行う 2 つのスレッドがある場合、つまり読み取りと書き込みの目的で同じオブジェクトにアクセスする複数のスレッドがある場合は、violetes キーワードを使用する必要があります。他のスレッドがそこで実行を停止しない限り、スレッドのブロックが保証されるため、この場合、同期を行う必要があります。これは、次のような違反キーワードよりもさらに多くの機能を提供するためです。
メソッドだけでなくステートメントのブロックでも使用できます。つまり、メソッド全体を同期する必要はありません。同期したいコードをブロック内に記述することもできます。
揮発性変数の値を読み書きするとき、値はメインメモリに直接読み書きされますが、これは良い習慣ではなく、キャッシュに比べてコストもかかります。したがって、不安定なキーワードを使用する前によく考えてください。それはあなたのパフォーマンスに直接影響します。
相互の応答に依存しない複数のスレッドがあるとします。つまり、この場合、読み取りと書き込みが互いに独立して volatile キーワードを使用するとします。しかし、以下で説明する volatile キーワードの使用が不適切なケースがもう 1 つあります。
Suppose thread has generated the first value of the volatile variable, and this current value will be used further to generate the new volatile variable values; in this case, this volatile keyword is not a good fit to generate the correct result; this condition will lead to a race condition were all thread going to read the same value but generate the new value for them and write the value to main memory and override each other values, so this will leads to the wrong result, or we can say data inconsistency issue, so here volatile keyword is not good enough to avoid this case we have to move to synchronization where we have to types to make our code synchronized, i.e. synchronized method and synchronized statement.
Code:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TvvApplication { private static final Logger LOGGER = LoggerFactory.getLogger(TvvApplication.class); private static final Object aclock = new Object(); private static final Object aclock1 = new Object(); private static volatile int MY_INT = 0; public static void main(String[] args) { System.out.println("without block"); System.out.println("with block calling static method :: "); testBlock(); } static void testBlock1() { synchronized (aclock1) { MY_INT = MY_INT + 1; System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block one:: "+ MY_INT); } } static void testBlock() { synchronized (aclock) { MY_INT = MY_INT + 1; System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block two:: "+ MY_INT); } } }
Output :
<img src="https://img.php.cn/upload/article/000/000/000/172500598784733.png" alt="Javaの揮発性キーワード" >
So this can provide thread safety when data does not depend on each other; if data depends, we should go for synchronization.
以上がJavaの揮発性キーワードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。