JAvaマルチスレッドシリーズ1--スレッド実装とスケジューリング

12406 ワード

JAvaの重要な機能の一つは、内部でマルチスレッドをサポートすることです.この一連の文章では、javaマルチスレッドの基礎知識を詳しく分析します.
マルチスレッドの概要
マルチスレッド導入
  • プログラムは実行フローが1つしかないので、このようなプログラムは単一スレッドプログラムです.
  • プログラムに複数の実行プロセスがある場合、そのプログラムはマルチスレッドプログラムである.

  • ≪プロセス|Process|emdw≫:実行中のプログラムは、システムがリソースの割り当てと呼び出しを行う独立した単位です.各プロセスには、独自のメモリ領域とシステムリソースがあります.
    スレッド:プロセス内の単一の順序制御フローであり、実行パスです.1つのプロセスに実行パスが1つしかない場合は、単一スレッドプログラムと呼ばれます.
    1つのプロセスに複数の実行パスがある場合は、マルチスレッドプログラムと呼ばれます.
    Javaプログラムの動作原理
    JAvaコマンドはjava仮想マシンを起動し、JVMを起動します.アプリケーションを起動したのと同じです.つまり、プロセスを起動しました.プロセスは自動的にプライマリ・スレッドを起動し、プライマリ・スレッドはクラスのmainメソッドを呼び出します.したがってmainメソッドはプライマリスレッドで実行されます.これまでのすべてのプログラムは単一スレッドでした.
    JAva仮想マシンはマルチスレッドです.メインスレッドのほかにゴミ回収スレッドがあるからです.
    マルチスレッド実装スキーム
    方式1:Threadクラスを継承する手順1、カスタムクラスMyThreadはThreadクラスを継承する.2、MyThreadクラスでrun()3を書き換える、オブジェクトを作成する4、スレッドを起動する
    次のコード:
    /*
     *      run()  ,    ?
     *                   。
     *      ,               ,java   Thread   run()              。
     */
    public class MyThread extends Thread {
        @Override
        public void run() {
            //     ,                。         
            for (int x = 0; x < 300; x++) {
                System.out.println(x);
            }
        }
    }
    public class MyThreadDemo {
        public static void main(String[] args) {
            //         
            MyThread my1 = new MyThread();
            MyThread my2 = new MyThread();
            my1.start();
            my2.start();
        }
    }

    手順:
    1、カスタムクラスMyRunnable実装Runnableインタフェース2、書き換えrun()メソッド3、MyRunnableクラスのオブジェクト4、Threadクラスのオブジェクトを作成し、Cステップのオブジェクトを構築パラメータとして渡す
    public class MyRunnable implements Runnable {
     
        @Override
        public void run() {
            for (int x = 0; x < 100; x++) {
                //                 Thread     ,         
                System.out.println(Thread.currentThread().getName() + ":" + x);
            }
        }
    }
    /*
     *   2:  Runnable  
     *   :
     *         A:    MyRunnable  Runnable  
     *         B:  run()  
     *         C:  MyRunnable    
     *         D:  Thread    ,  C             
     */
    public class MyRunnableDemo {
        public static void main(String[] args) {
            //   MyRunnable    
            MyRunnable my = new MyRunnable();
     
            //   Thread    ,  C             
            // Thread(Runnable target)
            Thread t1 = new Thread(my);
            Thread t2 = new Thread(my);
            t1.setName("zhangsan");
            t2.setName("lisi");
     
            // Thread(Runnable target, String name)
            Thread t1 = new Thread(my, "zhangsan");
            Thread t2 = new Thread(my, "lisi");
     
            t1.start();
            t2.start();
        }
    }

    インタフェース方式を実現するメリット:
    1.Javaシングル継承による限界を回避できます.
    2.複数の同じプログラムのコードが同じリソースを処理する場合に適しており、スレッドとプログラムのコード、データを有効に分離し、オブジェクト向けの設計思想をよりよく体現している.
    スレッド名の取得と設定
    Threadクラスの基本的な取得と設定方法:
    public final String getName()
    public final void setName(String name)
    実際には構築方法でスレッドに名前を付けることもできます
    mainメソッドが存在するスレッド名を取得するにはどうすればいいですか?
    public static Thread currentThread()
    これにより、任意のメソッドが存在するスレッド名を取得できます.
    サンプルコードは次のとおりです.
    public class MyThread extends Thread {
        public MyThread() {
        }
        
        public MyThread(String name){
            super(name);
        }
        @Override
        public void run() {
            for (int x = 0; x < 100; x++) {
                System.out.println(getName() + ":" + x);
            }
        }
    }
    public class MyThreadDemo {
        public static void main(String[] args) {
            //       
            //    +setXxx()
             MyThread my1 = new MyThread();
             MyThread my2 = new MyThread();
            //         
             my1.setName("zhangsan");
             my2.setName("lisi");
             my1.start();
             my2.start();
            
            //            
             MyThread my1 = new MyThread("zhangsan");
             MyThread my2 = new MyThread("lisi");
             my1.start();
             my2.start();
            
            //    main            ,     ?
            //public static Thread currentThread():             
            System.out.println(Thread.currentThread().getName());
        }
    }

    スレッドスケジューリング
    我々のコンピュータにCPUが1つしかない場合、CPUはある時点で1つの命令しか実行できず、スレッドはCPUタイムスライス、すなわち使用権を得てこそ、命令を実行することができる.ではJavaはどのようにスレッドを呼び出しますか?
    スレッドには2つのスケジューリングモデルがあります.
  • 分時スケジューリングモデルのすべてのスレッドはCPUの使用権を順番に使用し、各スレッドがCPUを占有するタイムスライス
  • を平均的に割り当てる.
  • プリエンプトスケジューリングモデルは、優先度の高いスレッドにCPUを優先的に使用させ、スレッドの優先度が同じであれば、ランダムに1つ選択され、優先度の高いスレッドで取得されるCPUタイムスライスは比較的多い.

  • Javaはプリエンプトスケジューリングモデルを使用しています.
    public final int getPriority()
    public final void setPriority(int newPriority)
    サンプルコードは次のとおりです.
    public class ThreadPriority extends Thread {
        @Override
        public void run() {
            for (int x = 0; x < 100; x++) {
                System.out.println(getName() + ":" + x);
            }
        }
    }
    /*
     *         public final int getPriority():          
     *              ?
     *         public final void setPriority(int newPriority):        。 
     * 
     *   :
     *                 5。
     *                  :1-10。
     *                         CPU       ,         ,                   。
     *         
     * 
     */
    public class ThreadPriorityDemo {
        public static void main(String[] args) {
            ThreadPriority tp1 = new ThreadPriority();
            ThreadPriority tp2 = new ThreadPriority();
            ThreadPriority tp3 = new ThreadPriority();
     
            tp1.setName("zhangsan");
            tp2.setName("lisi");
            tp3.setName("wangwu");
     
            //        
            System.out.println(tp1.getPriority());
            System.out.println(tp2.getPriority());
            System.out.println(tp3.getPriority());
     
            //        
            // tp1.setPriority(100000);
            
            //          
            tp1.setPriority(10);
            tp2.setPriority(1);
            tp1.start();
            tp2.start();
            tp3.start();
        }
    }