ホームページ >Java >&#&チュートリアル >Java 開発におけるマルチスレッド実装とスレッド セーフ
● 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
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()
マルチスレッドの実装方法
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"); } } }
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クラスです。
thread.Join は、指定されたスレッドを現在のスレッドに追加し、交互に実行される 2 つのスレッドを順次実行スレッドにマージできます。たとえば、スレッド A の Join() メソッドがスレッド B で呼び出された場合、スレッド A の実行が完了するまでスレッド B は実行を継続しません。
t.join(); //これより前に呼び出しスレッドの実行を完了させます。
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); } }
notify メソッドは、待機中の (オブジェクトの) スレッドを起動し、スレッドの実行を開始するだけです。したがって、オブジェクトを待機しているスレッドが複数ある場合、このメソッドはそのうちの 1 つのスレッドのみを起動し、どのスレッドを選択するかは、オペレーティング システムのマルチスレッド管理の実装によって異なります。
notifyAll は、(オブジェクト) を待っているすべてのスレッドを起動しますが、どのスレッドが最初に処理するかはオペレーティング システムの実装によって異なります。
これらのメソッドは、「プロデューサー-コンシューマー」問題で使用できます。コンシューマーはキュー内のオブジェクトを待機するスレッドであり、プロデューサーはキュー内のオブジェクトを解放して他のスレッドに通知するスレッドです。
以上がJava 開発におけるマルチスレッド実装とスレッド セーフの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。