Day 20 Java学習ノート——マルチスレッド学習

9851 ワード

help—>Keymap Referenceショートカットキーを見つけます

Javaマルチスレッド


1.プロセスとスレッド


1.1シリアルとパラレル

  • シリアル:複数のタスクが順番に実行されます.
  • パラレル:複数のタスクが同時に実行されます.

  • 1.2並行と同時

  • 並列:複数のCPUインスタンスまたは複数のマシンが同時に論理処理を実行し、真の同時である.
  • 同時:CPUスケジューリングアルゴリズムによって、ユーザーに同時に実行されるように見せるが、実際にはCPU操作レベルは本当の同時ではない.

  • 1.3プロセスとスレッド

  • プロセス:
  • は独立した実行環境を有する.
  • は、完全なプライベート基本ランタイムリソースを備えています.
  • 各プロセスには独自のストレージスペースがあります.

  • スレッド:
  • は、軽量レベルのプロセスと呼ばれることがある.
  • 新しいスレッドを作成するために必要なリソースは、新しいプロセスを作成するリソースよりも少ない.

  • 1プロセスには少なくとも1つのスレッドがあります.

  • 1.4スレッドステータス

  • は一般的にスレッドの同時処理と呼ばれ、プロセスの同時処理は複雑すぎる.
  • インスタンス化
  • newステータス(初期):スレッドオブジェクトを作成します.
  • start状態
  • 運転状態:
  • 準備状態:startの後、直接準備状態に来ます.
  • 運転中状態:
  • ブロック状態:同期文synchronized
  • 待機状態:
  • 待機:書き出しパラメータはタイムアウト待機である.
  • タイムアウト待ち:
  • 終了状態:スレッドが実行済みであることを示す
  • 2.スレッドオブジェクト


    2.1スレッド定義:

  • 実装Runnableインタフェース:スレッドオブジェクト
  • に含める方法を定義するRunnable実行を提供する.
    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("HelloRunnable");
        }
    
  • は、Threadクラス:サブクラスThreadを継承する.Threadクラス自体でRunnableを実装するがrunメソッドは機能しない.アプリケーションは、サブクラスThreadが独自の実装runを提供することができる.
  • public class HelloThread extends Thread {
    
        public void run() {
            System.out.println("HelloThread");
        }
    

    2.2スレッド名


    すべてのスレッドプログラムの実行は、毎回異なる実行結果であり、各スレッドを区別するには、スレッドの名前に依存する必要があります.スレッドの名前は、一般的に起動前にプロセス定義され、起動したスレッドに対して名前を変更したり、異なるスレッドに重複名を設定したりすることは推奨されません.
    //Runnable :
    public class HelloRunnableName implements Runnable {
        @Override
        public void run() {
            System.out.println(" :" + Thread.currentThread().getName());
        }
    //Thread 
    public class HelloThreadName extends Thread {
        public HelloThreadName(String name) {
            // super(name);
            this.setName(name);
        }
        @Override
        public void run() {
            super.run();
            System.out.println(" :" + Thread.currentThread().getName());
        }
    

    2.3スレッド優先度

  • スレッド優先度の範囲は1~10であり、デフォルトの優先度は5である.最高は10です.
  • //Runnable :
        public static void main(String[] args) {
            ThreadPriority threadPriority = new ThreadPriority();
            Thread thread1 = new Thread(threadPriority);
            thread1.setName(" 1");
            thread1.setPriority(Thread.MIN_PRIORITY);
            Thread thread2 = new Thread(threadPriority);
            thread2.setName(" 2");
            thread2.setPriority(Thread.MAX_PRIORITY);
            thread1.start();
            thread2.start();
        }
    }
    

    2.4スレッドスリープ


    Thread.sleepは、現在のスレッドを指定した期間内に実行を一時停止させます.これは、プロセッサ時間をアプリケーションの他のスレッドまたはコンピュータシステム上で実行されている可能性のある他のアプリケーションに使用できるようにする有効な方法です.
  • sleep(long millis)

  • 2.5スレッドの礼譲:


    Threadクラスでは、yield()メソッドを使用して、現在実行中のスレッドにリソースを他のスレッドに譲ることができることを通知するアラートメソッドが提供されていますが、これは単なるヒントであり、現在のスレッドがリソースを譲ることを保証するメカニズムはありません.
  • yield()メソッド
  • 2.6スレッド連携:


    joinメソッドでは、あるスレッドが別のスレッドの完了を待つことができます.tがThreadがスレッドを実行しているオブジェクトである場合、t.join();tのスレッドが終了するまで、現在のスレッドは実行を一時停止します.リロードjoinでは、プログラマが待機時間を指定できます.ただし、同じsleepでは、joinはOSに依存してタイミングを計るので、joinが指定した時間に完全に待機すると仮定するべきではありません.
  • t.join();

  • 2.7スレッド停止


    Javaでは、実行中のスレッドを終了するには、次の3つの方法があります.
  • は、スレッドが正常に終了するように終了フラグを使用し、すなわちrunメソッドが完了するとプロセスを終了する.
  • stop強制中断スレッド(この方法は無効期限切れの方法)を使用し、使用を推奨しません.
  • interruptメソッドを使用してスレッドを中断し、
  • を推奨しない.

    2.8デーモンスレッド

  • Javaスレッドは、ユーザースレッドとデーモンスレッドの2つに分けられます.
  • ユーザースレッド:システムの作業スレッドは、このプログラムが完了するビジネスマンの操作を完了します.
  • デーモンスレッド:特殊なスレッドで、その名前と同じように、システムのデーモンであり、バックグラウンドでごみ回収スレッドなどのシステム的なサービスを黙々と完了しています.

  • ユーザスレッドがすべて終了すると、このプログラムは何もできないことを意味します.デーモンスレッドがデーモンするオブジェクトが存在しない場合、アプリケーション全体が終了します.
    ここ栗:亀とウサギの競走

    3.スレッド同期


    3.1スレッドの競合

  • 異なるスレッドで同じデータに作用する2つの操作が実行されると、干渉が発生し、これは、2つの操作が複数のステップから構成され、ステップが順次重なることを意味する.
  • が取得した現在値c.
  • 検索された値に1を加算する.
  • は、増加した値をcに格納する.


  • ここ栗:切符売りたちは100枚の切符を売っています

    3.2同期文

  • 同期文(synchronized statements):同期コードを作成する方法の1つは、同期文を使用することです.同期方法とは異なり、同期文は内部ロックを提供するオブジェクトを指定する必要があります.同期文は、細粒度同期による同時性の向上に役立ちます.
  • 同期メソッド(synchronized methods):synchronizedキーワードを宣言に追加するだけで
  • こちら栗:同期後の販売員を増やして切符を売る

    4.スレッドデッドロック

  • デッドロックは特定のプログラム状態であり、エンティティ間では、循環依存によって互いに自重を待っているため、前進を続ける個体はいない.
  • デッドロックはスレッド間だけでなく、リソース独占が存在するプロセス間でもデッドロックが発生する可能性があります.通常、私たちの多くはマルチスレッドシーンに焦点を当てているデッドロックであり、2つ以上のスレッドの間で、互いに必要なロックを持っているため、互いに待機し、永遠にブロック状態にあることを意味します.

  • 5.スレッド調整

  • wait()メソッドとnotify()メソッド;
  • デッドロック発生条件
  • 反発条件
  • 要求保持条件
  • 無剥奪条件
  • サイクル待ち条件
  • public class ThreadCoordinate {
    
        public static void main(String[] args) {
            CoordinateA coordinateA = new CoordinateA();
            Thread threadA = new Thread(coordinateA, " 1");
            CoordinateB coordinateB = new CoordinateB();
            Thread threadB = new Thread(coordinateB, " 2");
            threadA.start();
            threadB.start();
        }
    }
    class CoordinateA implements Runnable {
        @Override
        public void run() {
            synchronized ("A") {
                System.out.println(Thread.currentThread().getName() 
    		+ " A , B 。。。");
                try {
                    "A".wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized ("B") {
                    System.out.println(Thread.currentThread().getName() 
    		+ " A B ");
                }
            }
        }
    }
    class CoordinateB implements Runnable {
        @Override
        public void run() {
            synchronized ("B") {
                System.out.println(Thread.currentThread().getName() 
    		+ " B , A 。。。");
                synchronized ("A") {
                    System.out.println(Thread.currentThread().getName() 
    		+ " B A ");
                    "A".notify();
                }
            }
        }
    }
    
    

    怠け者の単例モード


    6.高度な同時実行オブジェクト


    6.1スレッド定義

  • Callableインタフェース
  • を実現する.

    6.2スレッド同期:ロック対象


    同期コードは、単純な再ロックに依存します.このロックは使いやすいが、多くの制限がある.java.util.concurrent.locksパッケージは、より複雑なロック習慣をサポートします.ロックオブジェクトの動作は、同期コードで使用される暗黙的なロックと非常に似ています.暗黙的なロックと同様に、一度にロックオブジェクトを持つスレッドは1つしかありません.ロックオブジェクトはまた、wait/notifyが関連するConditionオブジェクトを介してメカニズムをサポートします.
  • reentrantLock.lock()
  • reentrantLock.unlock()

  • 6.3スレッドプール


    Javaでスレッドを作成および破棄するのは、システム呼び出しが必要な高価な操作です.スレッドの頻繁な作成と破棄は、システムのパフォーマンスに影響します.
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class ThreadPool implements Runnable {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            executorService.execute(new ThreadPool());
            executorService.execute(new ThreadPool());
            executorService.execute(new ThreadPool());
            executorService.shutdown();
        }
    }
    

    6.4同時集合:BLockingQueue


    BlockingQueue実装は主に生産者-消費者キューに用いられるように設計されており、BlockingQueueが空であればBlockingQueueから物を取り出す操作はブロックされて待機状態に入り、BlockingQueueが物を入れてから呼び覚まされる.同様に、BlockingQueueがいっぱいであれば、中に物を預けようとする操作もブロックされて待機状態に入り、BlockingQueueに空間があるまで呼び覚まされません.
    // : 
    import java.util.concurrent.BlockingQueue;
    public class Consumer implements Runnable {
        BlockingQueue blockingQueue;
        public Consumer(BlockingQueue blockingQueue) {
            this.blockingQueue = blockingQueue;
        }
        @Override
        public void run() {
            try {
                while (true) {
                    Product product = blockingQueue.take();
                    System.out.println(" : " + product.getName());
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    6.5静的エージェント


    静的エージェントは,コンパイル時にエージェントクラスと被エージェントクラスの関係を決定する.

    6.6 Lambda式


    Lambda式は、Java 8のリリースを推進する最も重要な新しい特性である閉パッケージとも呼ばれます.Lambdaは、関数をメソッドのパラメータ(関数をパラメータとしてメソッドに渡す)として許可します.Lambda式を使用すると、コードをより簡潔でコンパクトにすることができます.
    public class LambdaExpression {
        // 2、 
        static class Love2 implements ILove {
            @Override
            public void lambda() {
                System.out.println("I Love Lambda 2");
            }
        }
        public static void main(String[] args) {
            // 1、 
            ILove love = new Love();
            love.lambda();
            
            // 2、 
            ILove love2 = new Love2();
            love2.lambda();
            
            // 3、 
            class Love3 implements ILove {
                @Override
                public void lambda() {
                    System.out.println("I Love Lambda 3");
                }
            }
            ILove love3 = new Love3();
            love3.lambda();
            
            // 4、 
            ILove love4 = new ILove() {
                @Override
                public void lambda() {
                    System.out.println("I Love Lambda 4");
                }
            };
            love4.lambda();
            
            // 5、Lambda
            ILove love5 = () -> {
                System.out.println("I Love Lambda 5");
            };
            love5.lambda();
        }
    }
    
    

    6.7ArrayList


    ArrayListはスレッドが安全ではありません.彼のaddメソッドにはsynchronized同期ロック制御はありません.

    6.8CopyOnWriteArray


    CopyOnWriteArrayListは、ArrayListのスレッドセキュリティの変形であり、すべての可変動作(add、setなど)は、下位配列の新しいコピーによって実現される.