Java 並行プログラミングの volatile キーワードの概要 (例付き)

不言
リリース: 2018-11-20 15:58:09
転載
2503 人が閲覧しました

この記事では、Java 同時プログラミングの volatile キーワードについて説明します (例を示します)。必要な方は参考にしていただければ幸いです。

volatile-Description

  • volatile キーワードの役割は、変数が複数のスレッドで表示されることです。 volatile キーワードはアトミックではありません

  • アトミック操作を実装したい場合は、アトミック クラスの一連のオブジェクトを使用することをお勧めします。アトミック操作をサポートします (アトミック クラスは保証するだけであることに注意してください)独自のメソッドのアトミック性であり、操作のアトミック性を複数回保証するものではありません)

  • 1. volatile :

の役割。 volatile キーワードは、変数が複数のスレッドで表示されることを意味します。

  • 例:
  • RunThread.java

説明: Java では、各スレッドには作業メモリ領域があり、すべてのスレッドで共有される情報がメイン メモリに保存されます。スレッドが実行されると、これらの変数は独自の作業メモリ領域で操作されます。共有変数にアクセスするには、通常、スレッドはまずロックを取得して現在のスレッドのメモリ作業領域をクリアし、これらの共有変数をすべてのスレッドの共有メモリ領域から独自の作業メモリ領域に正しくロードします。スレッドのロックを解除すると、作業メモリ内の変数の値が共有メモリ領域に書き込まれます。
#* スレッドが実行できる操作は、使用 (use)、割り当て (assgin)、ロード (load)、ストア (store)、ロック (lock)、ロック解除 (ロック解除) です。 ) ;

  • * メイン メモリで実行できる操作は、読み取り (読み取り)、書き込み (書き込み)、ロック (ロック)、ロック解除 (ロック解除) です。各操作はアトミックです。の。

  • * volatile の機能は、スレッドの作業メモリ領域で変数を読み取るのではなく、スレッドにメイン メモリ (共有メモリ) 内の変数を強制的に読み取ることで、複数のスレッドを実現します。が見える。これは、スレッドセーフな可視性も満たします。

  • public class RunThread extends Thread{
    
        private volatile boolean isRunning = true;
        private void setRunning(boolean isRunning){
            this.isRunning = isRunning;
        }
    
        public void run(){
            System.out.println("进入run方法..");
            int i = 0;
            while(isRunning == true){
                //..
            }
            System.out.println("线程停止");
        }
    
        public static void main(String[] args) throws InterruptedException {
            RunThread rt = new RunThread();
            rt.start();
            Thread.sleep(1000);
            rt.setRunning(false);
            System.out.println("isRunning的值已经被设置了false");
        }
    }
    ログイン後にコピー
  • 2。 volatile キーワードは非アトミックですが、複数のスレッド間での可視性はありません。これは軽量の同期型と見なすことができ、同期型よりもパフォーマンスがはるかに優れており、ブロッキングが発生しません (多くのオープン ソース アーキテクチャでは、Netty の基礎となるコードは広範囲に使用されると不安定になります。目に見える netty のパフォーマンス)

#* 注意事項: 通常、volatile は複数のスレッドから見える変数操作に使用され、synchronized;

# の同期効果を置き換えることはできません。
    ##例: concurrent.java
  • 説明: volatile キーワードには可視性のみがあり、原子性はありません。

    import java.util.concurrent.atomic.AtomicInteger;
    /**
    * volatile关键字不具备synchronized关键字的原子性(同步)
    * @@author Maozw
    *
    */
    public class VolatileNoAtomic extends Thread{
        //private static volatile int count;
        private static AtomicInteger count = new AtomicInteger(0);
        private static void addCount(){
          for (int i = 0; i < 1000; i++) {
            //count++ ;
            count.incrementAndGet();
          }
          System.out.println(count);
        }
    
        public void run(){
          addCount();
        }
    
        public static void main(String[] args) {
    
          VolatileNoAtomic[] arr = new VolatileNoAtomic[100];
          for (int i = 0; i < 10; i++) {
            arr[i] = new VolatileNoAtomic();
          }
    
          for (int i = 0; i < 10; i++) {
            arr[i].start();
          }
        }
    }
    ログイン後にコピー

* アトミック操作を実装したい場合は、アトミック クラスの一連のオブジェクトを使用することをお勧めします。アトミック操作をサポートします (アトミック クラスは、アトミック クラスのアトミック性のみを保証することに注意してください)独自のメソッドであり、複数の操作の原子性は保証されません)
例:

  • 説明:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AtomicUse {
    
    private static AtomicInteger count = new AtomicInteger(0);
    
        //多个addAndGet在一个方法内是非原子性的,需要加synchronized进行修饰,保证4个addAndGet整体原子性
        /**synchronized*/
        public synchronized int multiAdd(){
            try {
              Thread.sleep(100);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
            count.addAndGet(1);
            count.addAndGet(2);
            count.addAndGet(3);
            count.addAndGet(4); //+10
            return count.get();
        }
        public static void main(String[] args) {
    
          final AtomicUse au = new AtomicUse();
    
          List<Thread> ts = new ArrayList<Thread>();
          for (int i = 0; i < 100; i++) {
            ts.add(new Thread(new Runnable() {
              @Override
              public void run() {
                System.out.println(au.multiAdd());
              }
            }));
          }
          for(Thread t : ts){
            t.start();
          }
        }
    }
    ログイン後にコピー

以上がJava 並行プログラミングの volatile キーワードの概要 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート