JAVAマルチスレッドの理解


マルチスレッド
  • 前言
  • プロセスとスレッドとは何ですか?
  • 初認識スレッド
  • スレッドのいくつかの作成方法
  • はThreadクラス
  • を継承する.
  • Runnableインタフェース
  • を継承する
  • CallableとFutureを使用してスレッド
  • を作成
  • スレッドプールを使用してスレッド
  • を作成
  • いくつかの作成方法の長所と短所
  • をまとめる

    前言
    现代のコンピュータの処理能力はますます强大になって、マルチスレッドはプログラマーが熟练して応用しなければならない技能と言えて、私は自分がマルチスレッドを勉强してまとめた要点を记录して読者に少しの启発があることを望みます.
    プロセスとスレッドとは?
    マルチスレッドを学ぶ前に、プロセスとスレッドを明確に認識しなければなりません.
    プロセス:プログラムが1つのデータセットで実行するプロセスで、それはシステムが資源の分配とスケジューリングを行う基本単位です.スレッド:オペレーティングシステムの演算スケジューリングの最小単位で、それはプロセスの中に含んで、プロセスの実際の運営単位です.
    しょしきスレッド
    public class ThreadBegin {
         
        //    
        public static void main(String[] args) {
         
            System.out.println(Thread.currentThread().getName());
        }
    }
    

    ここでmainを出力します.このmainはメインスレッドを表します.(注意しなければならないのは、このmainとメインメソッド名mainは何の関係もありません.名前が同じだけです.つまり、スレッドの名前を表し、メソッドの名前を表します).マルチスレッドを学ぶために必要なのは、どのようにスレッドを開くかを知っておく必要があります.スレッドを開く方法
    スレッドの作成方法
    Threadクラスの継承
    作成手順は3つあります.
  • 独自のスレッドクラス継承Threadを作成し、そのクラスのrun()メソッドを書き換えます.run()メソッドでは、このスレッドが実行するタスクが必要です.
  • あなたが書いたスレッドクラスのインスタンス、すなわちスレッドオブジェクトを作成します.
  • インスタンスのstart()メソッドを呼び出し、スレッドを起動する.
  • 	public static class MyThread extends Thread{
         
            @Override
            public void run() {
         
                System.out.println("  Thread      ");
            }
        }
    
        public static void main(String[] args) {
         
            myThread myThread = new myThread();
            myThread.start();
        }
    

    Runnableインタフェースの継承
    作成ステップも3ステップであり、継承Threadと基本的に似ています.
  • 自分のスレッドクラスを作成してRunnableを継承し、そのクラスのrun()メソッドを書き換えます.run()メソッドでは、このスレッドが実行するタスクが必要です.
  • あなたが書いたスレッドクラスのインスタンスを作成し、このインスタンスをThreadのtarget(Threadの構築方法の一つはRunnableインタフェースに転送することである)として、ここのThreadは作成したスレッドオブジェクトとして計算される.
  • スレッドオブジェクトのstart()メソッドを呼び出し、スレッドを起動する.
  • 	public static class MyThread1 implements Runnable{
         
    
            @Override
            public void run() {
         
                System.out.println("  Runnable       ");
            }
        }
    
        public static void main(String[] args) {
         
            MyThread1 myThread1 = new MyThread1();
            Thread thread = new Thread(myThread1);
            thread.start();
        }
    

    ここでは、Runnableインタフェースを継承してマルチスレッドを実現する利点について説明する必要があります.
  • は、Threadクラスを継承する単一の継承の限界を回避する.
  • Runnableインタフェースを実装すると、スレッドオブジェクトとスレッドタスクの結合性が低下し、プログラムの拡張性が向上します.
  • Runnableインタフェースはスレッドを個別にオブジェクトのパッケージ化することを実現し、よりオブジェクト向けの考え方に合致する.したがって、実際の開発では、Runnableインタフェースを継承してマルチスレッドを実現することができる.ここでは匿名の内部クラス作成方法とlambda式作成スレッドを添付する方法で、多くのコード
  • を削減することができる.
     //         
        public static void myThreadNiMing(){
         
            new Thread(new Runnable() {
         
                @Override
                public void run() {
         
                    System.out.println("           "+Thread.currentThread().getName());
                }
            }).start();
        }
    
        //lambda       
        public static void myThreadLambda(){
         
            new Thread(()->{
         
                System.out.println("lambda         "+Thread.currentThread().getName());
            }).start();
        }
    
        public static void main(String[] args) {
         
            myThreadLambda();
            myThreadNiMing();
        }
    

    CallableとFutureを使用したスレッドの作成
    この2つのインタフェースでスレッドを作成するには、この2つのインタフェースの役割を知っておく必要があります.次に、Runnableインタフェースを実装してマルチスレッドを作成する場合、Threadクラスの役割はrun()メソッドをスレッドの実行体にパッケージすることです.では、任意のメソッドを直接スレッドの実行体にパッケージすることができますか?JAVA 5から、JAVAはRunnableインタフェースの強化版であるCallableインタフェースを提供し、Callableインタフェースはスレッド実行体としてcall()メソッドを提供するが、call()メソッドはrun()メソッドよりも機能が強く、call()メソッドの機能の強さは以下の通りである.
    1、call()メソッドには戻り値があります.2、call()メソッドは放出異常を宣言することができる.
    ここから,スレッドのスレッド実行体がcall()メソッドであるThreadのtargetとしてCallableオブジェクトを完全に提供できることが分かる.しかし、問題は、CallableインタフェースはJAVAに追加されたインタフェースであり、Runnableインタフェースのサブインタフェースではないため、Callableオブジェクトは直接Threadのtargetとして使用できないことです.もう1つの理由は、call()メソッドには戻り値があり、call()メソッドは直接呼び出されるのではなく、スレッド実行体として呼び出されるため、ここではcall()メソッドの戻り値を取得する問題に関する.そこで、JAVA 5は、Callableインタフェースにおけるcall()メソッドの戻り値を表すFutureインタフェースを提供し、FutureインタフェースにFutureインタフェースを実現し、Runnableインタフェースを実現するFuture Task実装クラスを提供しているので、FutureTaskはThreadクラスのtargetとすることができ、CallableオブジェクトがThreadクラスのtargetとして機能しないという問題も解決している.
    手順は次のとおりです.
  • Callableインタフェース実装クラスを作成し、スレッド実行体として機能し、Callable実装クラスのインスタンスを作成するcall()メソッドを実装する.
  • FutureTaskクラスを使用してCallableオブジェクトをパッケージ化し、このFutureTaskオブジェクトはCallableオブジェクトのcall()メソッドの戻り値をカプセル化する.
  • FutureTaskオブジェクトをThreadオブジェクトのtargetとして使用して新しいスレッドを作成し、起動する.
  • FutureTaskオブジェクトのget()メソッドを呼び出して、サブスレッド実行終了後の戻り値を取得します.
  • public class ThirdThreadImp {
         
    	
    	public static void main(String[] args) {
         
    		
    		//  call()        lambda   ,      Callable      
    		FutureTask<Integer> task =  new FutureTask<Integer>((Callable<Integer>)()->{
         
    			int i = 0;
    			for(;i < 50;i++) {
         
    				System.out.println(Thread.currentThread().getName() + 
    						"              i   :" + i);	
    			}
    			//call()      
    			return i;
    		});
    		
    		for(int j = 0;j < 50;j++) {
         
    			System.out.println(Thread.currentThread().getName() + 
    					"         j   :" + j);
    			if(j == 20) {
         
    				new Thread(task,"       ").start();
    			}
    		}
    		try {
         
    			System.out.println("       :" + task.get());
    		} catch (Exception e) {
         
    			e.printStackTrace();
    		}
    	}
     
    }
    

    コード相関:1、上のコードはLambda式を使用し、Callableインスタンスを作成してFutureに入れることもできます.2、call()メソッドの戻り値タイプは、FutureTaskオブジェクトを作成したときの<>のタイプと一致します.コード解析:最後の行の出力のみを見ると、FutureTaskオブジェクトのget()メソッドを呼び出すには、サブスレッドが終了してから戻り値がある必要があります.
    スレッドプールを使用したスレッドの作成
    ここは紙幅が長いので,後で興味のあることを詳しく説明して歩くことができる.
    いくつかの作成方法の長所と短所をまとめる
    作成方法は、Threadを継承するクラスと、RunnableとCallableインタフェースを継承するクラスの2つに分けられる.
    Threadクラスを継承してマルチスレッドを実現する:利点:1、実現が簡単で、現在のスレッドを取得するには、Thread.currentThread()メソッドを呼び出す必要がなく、thisを直接使用して現在のスレッドを取得することができます.
    欠点:1、スレッドクラスはすでにThreadクラスを継承して、更に他のクラスを継承することができません;2、複数のスレッドは同じリソース(前に分析したメンバー変数iなど)を共有できない.
    RunnableインタフェースまたはCallableインタフェースを実装することによってマルチスレッドを実現する:
    利点:1、スレッドクラスはインタフェースを実現しただけで、他のクラスを継承することもできる.2、複数のスレッドは同じtargetオブジェクトを使用することができ、複数のスレッドが同じリソースを処理する場合に適している.
    欠点:1、このような方式によってマルチスレッドを実現し、第1類の方式に比べて、プログラミングが複雑である.2.現在のスレッドにアクセスするには、Thread.currentThread()メソッドを呼び出す必要があります.
    第2の方法でスレッドを作成することを提案する.