ホームページ >Java >&#&チュートリアル >Java 開発におけるマルチスレッド実装とスレッド セーフ

Java 開発におけるマルチスレッド実装とスレッド セーフ

无忌哥哥
无忌哥哥オリジナル
2018-07-23 09:36:301895ブラウズ

マルチスレッドの実装方法

● Thread クラスを継承してスレッド クラスを作成し、run メソッドをオーバーライドします。 run メソッドは、スレッドが完了する必要があるタスクを表します。 Thread クラスはすでに Thread クラスを継承しているため、他の親クラスから継承することはできません。

class ThreadTest extends Thread {  

    Thread thread;  

    public ThreadTest(Thread thread) {  
      this.thread = thread;  
  }  

   @Override  
   public void run() {  
      synchronized (thread) {  
          System.out.println("getObjectLock");  
         try {  
             Thread.sleep(9000);  
       } catch (InterruptedException ex) {  
          ex.printStackTrace();  
         }  
           System.out.println("ReleaseObjectLock");  
    }  
   }  
 }

● Runnable インターフェイスを実装してスレッド クラスを作成し、Runnable 実装クラスを定義し、run メソッドをオーバーライドします

  class RunnableImpl implements Runnable {  
    
     public void run() {  
          try {  
             System.out.println("Begin sleep");  
             Thread.sleep(2000);  
             System.out.println("End sleep");  
          } catch (InterruptedException e) {  
              e.printStackTrace();  
          }  
      }  
   }

● Callable インターフェイスを実装し、call() メソッドをオーバーライドします。call() は実行本体として機能しますスレッドと戻り値を持ちます

● スレッド プール、スレッド オブジェクトを生成するためにスレッド プールを使用します java.util.concurrent.ExecutorService、java.util.concurrent.Executors

Java はどのようにしてスレッドの安全性を実現しますか?排他的同期: 同時実行パッケージ内で同期には synchronized キーワードを使用することをお勧めします。その中には ReentrantLock クラスがあり、実装の効果は依然として元の synchronized を推奨します。 ● ノンブロッキング同期: 完了するにはハードウェア命令が必要です。 一般的に使用される命令は次のとおりです。 テスト アンド セット フェッチ アンド インクリメント スワップ コンペア アンド スワップ (CAS) ロード リンク/ストア条件 (LL/SC) 典型的なアプリケーション。 :

のAtomicInteger ● 同期なしの解決策: ローカル スレッドに変数を保存するため、複数のスレッドで同時にエラーが発生することはありません。 Javaで主に使用されるのはThreadLocalクラスです。


Join() メソッド

thread.Join は、指定されたスレッドを現在のスレッドに追加し、交互に実行される 2 つのスレッドを順次実行スレッドにマージできます。たとえば、スレッド A の Join() メソッドがスレッド B で呼び出された場合、スレッド A の実行が完了するまでスレッド B は実行を継続しません。

t.join(); //これより前に呼び出しスレッドの実行を完了させます。

t.join(1000); //t 個のスレッドを待機します。待機時間は 1000 ミリ秒で、タイムアウトは問題ありません

public class JoinTest implements Runnable{  

    public static int a = 0;  

    public void run() {  
        for (int k = 0; k < 5; k++) {  
            a = a + 1;  
        }  
    }  

    public static void main(String[] args) throws Exception {  
        Runnable r = new JoinTest();  
        Thread t = new Thread(r);  
        t.start();        
        t.join();//等待t线程完成后输出,可保证a=5;
        System.out.println(a);  
    }         
}

wait()

オブジェクトの wait メソッドには 3 つのオーバーロードされたメソッドがあり、そのうちの 1 つは wait( ) 他のスレッドが現在のスレッドをウェイクアップするために notification または NoticeAll メソッドを呼び出すまで、無期限 (常に) 待機します。他の 2 つのメソッド wait(long timeout) と wait(long timeout, int nanos) では、現在のスレッドがウェイクアップされる前に待機することができます。時間、timeout はミリ秒数、nanos はナノ秒数です。

notify()

notify メソッドは、待機中の (オブジェクトの) スレッドを起動し、スレッドの実行を開始するだけです。したがって、オブジェクトを待機しているスレッドが複数ある場合、このメソッドはそのうちの 1 つのスレッドのみを起動し、どのスレッドを選択するかは、オペレーティング システムのマルチスレッド管理の実装によって異なります。

notifyAll()

notifyAll は、(オブジェクト) を待っているすべてのスレッドを起動しますが、どのスレッドが最初に処理するかはオペレーティング システムの実装によって異なります。

これらのメソッドは、「プロデューサー-コンシューマー」問題で使用できます。コンシューマーはキュー内のオブジェクトを待機するスレッドであり、プロデューサーはキュー内のオブジェクトを解放して他のスレッドに通知するスレッドです。

マルチスレッドの実装方法

● Thread クラスを継承してスレッド クラスを作成し、run メソッドをオーバーライドします。run メソッドはスレッドが完了する必要があるタスクを表し、スレッド オブジェクトの start() を呼び出して開始します。スレッドの場合、スレッドクラスは Thread クラスを継承しているため、他の親クラスから継承することはできません。

class ThreadTest extends Thread {  

    Thread thread;  

    public ThreadTest(Thread thread) {  
      this.thread = thread;  
  }  

   @Override  
   public void run() {  
      synchronized (thread) {  
          System.out.println("getObjectLock");  
         try {  
             Thread.sleep(9000);  
       } catch (InterruptedException ex) {  
          ex.printStackTrace();  
         }  
           System.out.println("ReleaseObjectLock");  
    }  
   }  
 }

● Runnable インターフェイスを実装してスレッド クラスを作成し、Runnable 実装クラスを定義し、run メソッドをオーバーライドします

  class RunnableImpl implements Runnable {  
    
      public void run() {  
          try {  
              System.out.println("Begin sleep");  
              Thread.sleep(2000);  
              System.out.println("End sleep");  
          } catch (InterruptedException e) {  
              e.printStackTrace();  
           }  
       }  
   }

● Callable インターフェイスを実装し、call() メソッドをオーバーライドします。call() は実行本体として機能しますスレッドと戻り値を持ちます

● スレッド プール、スレッド オブジェクトを生成するためにスレッド プールを使用します java.util.concurrent.ExecutorService、java.util.concurrent.Executors

Java はどのようにしてスレッドの安全性を実現しますか?排他的同期: 同時実行パッケージ内で同期には synchronized キーワードを使用することをお勧めします。その中には ReentrantLock クラスがあり、実装の効果は依然として元の synchronized を推奨します。 ● ノンブロッキング同期: 完了するにはハードウェア命令が必要です。 一般的に使用される命令は次のとおりです。 テスト アンド セット フェッチ アンド インクリメント スワップ コンペア アンド スワップ (CAS) ロード リンク/ストア条件 (LL/SC) 典型的なアプリケーション。 :

のAtomicInteger ● 同期なしの解決策: ローカル スレッドに変数を保存するため、複数のスレッドで同時にエラーが発生することはありません。 Javaで主に使用されるのはThreadLocalクラスです。

Join() メソッド

thread.Join は、指定されたスレッドを現在のスレッドに追加し、交互に実行される 2 つのスレッドを順次実行スレッドにマージできます。たとえば、スレッド A の Join() メソッドがスレッド B で呼び出された場合、スレッド A の実行が完了するまでスレッド B は実行を継続しません。

t.join(); //これより前に呼び出しスレッドの実行を完了させます。

t.join(1000); //t 個のスレッドを待機します。待機時間は 1000 ミリ秒で、タイムアウトは問題ありません

public class JoinTest implements Runnable{  

    public static int a = 0;  

    public void run() {  
        for (int k = 0; k < 5; k++) {  
            a = a + 1;  
        }  
    }  

    public static void main(String[] args) throws Exception {  
        Runnable r = new JoinTest();  
        Thread t = new Thread(r);  
        t.start();        
        t.join();//等待t线程完成后输出,可保证a=5;
        System.out.println(a);  
    }         
}

wait()

オブジェクトの wait メソッドには 3 つのオーバーロードされたメソッドがあり、そのうちの 1 つは wait( ) 他のスレッドが現在のスレッドをウェイクアップするために notification または NoticeAll メソッドを呼び出すまで、無期限 (常に) 待機します。他の 2 つのメソッド wait(long timeout) と wait(long timeout, int nanos) では、現在のスレッドがウェイクアップされる前に待機することができます。時間、timeout はミリ秒数、nanos はナノ秒数です。

notify()

notify メソッドは、待機中の (オブジェクトの) スレッドを起動し、スレッドの実行を開始するだけです。したがって、オブジェクトを待機しているスレッドが複数ある場合、このメソッドはそのうちの 1 つのスレッドのみを起動し、どのスレッドを選択するかは、オペレーティング システムのマルチスレッド管理の実装によって異なります。

notifyAll()

notifyAll は、(オブジェクト) を待っているすべてのスレッドを起動しますが、どのスレッドが最初に処理するかはオペレーティング システムの実装によって異なります。
これらのメソッドは、「プロデューサー-コンシューマー」問題で使用できます。コンシューマーはキュー内のオブジェクトを待機するスレッドであり、プロデューサーはキュー内のオブジェクトを解放して他のスレッドに通知するスレッドです。

以上がJava 開発におけるマルチスレッド実装とスレッド セーフの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。