JAVAマルチスレッド(基本)

1.プロセスとスレッド

プロセスとスレッドの概念1.1

プロセスの概念:プログラムのオペレーティングシステムの実行サイクル(例:オープンとこれはプロセスであるQQのQQを閉じ)

                 プロセスは、オペレーティングシステムでリソース割り当ての最小単位

スレッドの概念タスク処理:

                 スレッドは、オペレーティングシステムのあるスケジューリングリソースの最小単位

プロセスとスレッドの違い

  • アドレス空間:プロセスの同じスレッドは、このプロセスのアドレス空間を共有し、そのプロセスは、アドレス空間とは無関係です
  • メモリリソース:リソースプロセスは互いに独立しているながら、同じプロセスのスレッドは、このプロセス、メモリ(スタックメモリが共有されていないメモリヒープおよびメソッド領域)のリソースを共有します
  • 両方をすることができ、同時に実行される(交互に実行する複数のタスクを切り替え)

1.2スレッドの状態

作成、準備、実行されている、ブロック、終了

2.マルチスレッド

2.1スレッドクラスの継承(Runnableをインタフェースを実装)

例:

class MThread extends Thread{
    private String cat;
    public MThread(String cat){
        this.cat = cat;
    }
    public void run(){
        for(int i = 0; i < 5;i++){
            System.out.println(this.cat+"喜欢"+i);
        }
    }
}
public class MyThread {
    public static void main(String[] args) {
        Thread thread1 = new MThread("小花");
        Thread thread2 = new MThread("小白");
        Thread thread3 = new MThread("桔子");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

なぜ、start()メソッドの代わりに、run()メソッドを呼び出しますか?

  • run()メソッドは、慣例マルチスレッドプログラムです。内部のrunメソッド内のすべてのマルチスレッドコード。
  • コールstart()メソッドは、スレッドが自動的に実行を呼び出します()メソッド
  • スレッドを開始する()メソッド、真のマルチスレッド動作を開始、実行メソッド本体のコードを待たず、この時間が完了し、次のコードに直接進むれます。
  • スレッドを開始するにはThreadクラス()メソッドを呼び出して起動し、その後、このスレッドは、状態(実行する)準備ができて、そして実行されていない、CPU時間スライスしたら、彼らはrun()メソッドを実行し始めます。
  • ラン()メソッドを使用して、直接、Runメソッドを呼び出した場合、プログラムはまだこのスレッドの唯一のメインスレッドで、クラスのちょうど一般的な方法であり、プログラムの実行は、唯一の道である、または順序を実行するために、または実行がメソッド本体の後に終了するのを待ちますあなたは、スレッドを書くために何の目的がないので、次のコードを実行し続けることができます。

2.1 Runnableを実装

例1:

class MThread implements Runnable{
    private String cat;
    public MThread(String cat){
        this.cat = cat;
    }
    public void run(){
        for(int i = 0; i < 5;i++){
            System.out.println(this.cat+"喜欢"+i);
        }
    }
}
public class MyThread {
    public static void main(String[] args) {
        Mthread thread1 = new MThread("小花");
        Mthread thread2 = new MThread("小白");
        Mthread thread3 = new MThread("桔子");
        new Thread(thread1).start();
        new Thread(thread2).start();
        new Thread(thread3).start();
    }
}

例2:匿名内部クラスを使用します

public class MyThread {
    public static void main(String[] args) {
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println("小花最调皮");
            }
        }).start();
    }
}

例3:Lamdba式を使用して

public class MyThread {
    public static void main(String[] args) {
        Runnable runnable = ()-> System.out.println("小花最调皮");
        new Thread(runnable).start();
    }
}

スレッドと(Runnableを利用)のRunnableを違い

  • リソースを共有しやすいのRunnableを実装
  • 単一継承の制限を回避
  • スレッドプールにのみ直接ではなく、クラスの継承スレッドに、Runnableを、呼び出し可能クラスのインタフェースを実現することができます

 

2.3呼び出し可能インターフェースを実装

class Mthread implements Callable{
    private int cat = 4;
    @Override
    public Object call() throws Exception {
        while(cat > 0){
            System.out.println("还有"+cat+"只猫");
            cat--;
        }
        return "猫咪回家了,撸猫明请早";
    }
}
public class MyThread {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> callable = new FutureTask<>(new Mthread());
        new Thread(callable).start();
        System.out.println(callable.get());
    }
}

実行のRunnable()メソッドは値を返しますが、多くの場合、例えば、いくつかのリターンそれが唯一のマルチスレッドの使用が呼び出し可能な達成することができ、その場合にはその結果を、完全に実行するいくつかのスレッドを持ち帰る可能性がある、いくつかの戻り値を必要としません。

操作3.マルチスレッドの一般的な方法

3.1スレッドのネーミングと作られました

ノースレッド名場合は、スレッドは自動的に名前が割り当てられています

  • 公共の最終同期ボイドのsetName(文字列名); //名前を設定するときにスレッドを作成
  • 公共のスレッド(Runnableをターゲット、文字列名); //スレッド名を設定します
  • 公共の最終文字列のgetName(); //スレッド名を取得します
public class MyThread{
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                //设置线程名称
                this.setName("小白");
                System.out.println(this.getName());
            }
        }.start();
        //通过构造方法设置名称
        new Thread("小花"){
            public void run(){
                System.out.println(this.getName());
            }
        }.start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                //获得当前线程名称
                System.out.println(Thread.currentThread().getName());
            }
        }).start();
    }
}

3.2スレッドがスリープ状態に(スリープ法)

SLEEP():続行する前に、所定の時間に、それを停止するスレッド。一方で、我々は、CPUを使用する権利を引き渡すますが、ロックを解除しません。現在のスレッドがスリープ、その後、オブジェクトのロックを保持している言い換えれば、他のスレッドがこのオブジェクトにアクセスすることはできません。そして、この方法の後に戻って遮断状態にスレッド、と呼ばれています。

  • パブリック静的ネイティブボイド睡眠(長いミリ)が例外:InterruptedExceptionをスローします
class MThread implements Runnable {
    private String cat;
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "喜欢" + i);
        }
    }
}

3.3スレッド譲歩(収率法)

収率は():実行する他のスレッドを支持して現在の実行スレッドを一時停止します。私たちは、CPUを使用する権利を引き渡すますが、特定の時間の制御を引き渡すことができません。そして、このメソッドを呼び出すと、ロックを解除しません。そして、このメソッドが呼び出された後、戻って準備状態にスレッド。

class MThread implements Runnable {
    private String cat;
    public void run() {
        for (int i = 0; i < 5; i++) {
                Thread.yield();
            System.out.println(Thread.currentThread().getName() + "喜欢" + i);
        }
    }
}

3.4join()メソッド

)(参加:このスレッドを待ちます。これは、スレッドが実行するための実行スレッドを実行した後に待機しなければならないと述べました。

public class MyThread{
    public static void main(String[] args) {
       Thread thread1 = new Thread(new Runnable() {
           @Override
           public void run() {
               for (int i = 0;i < 5;i++){
                   System.out.println(Thread.currentThread().getName());
               }
           }
       });
        Thread thread2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0;i < 5;i++){
                    try {
                        thread1.join();
                        System.out.println(Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread1.start();
        thread2.start();
    }
}

3.5スレッドの停止

  • フラグがセットされ、スレッドが正常終了であってもよいです。
class MThread implements Runnable {
    private boolean flag = true;
    @Override
    public void run() {
        int i = 1;
        while (flag) {
            try {
                Thread.sleep(1000);
                System.out.println("第"+i+"次执行,线程名称为"+Thread.currentThread().getName());
                i++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}
public class MyThread{
    public static void main(String[] args) throws InterruptedException {
        MThread myThread = new MThread();
        new Thread(myThread).start();
        Thread.sleep(4500);
        myThread.setFlag(false);
    }
}
  •  (非推奨)スレッドが終了を強制する方法を停止します

この方法は、stopメソッドが呼び出されたときに得られたすべてのロックスレッドをリリースする予定停止、スレッドオブジェクトのスレッドが実行を直ちに停止し、従って不完全な障害データを生成することができます。

  •  )(割り込みThreadクラスを使用してスレッドを中断することができます。

単に唯一の割り込みステータスを変更する()メソッドを中断し、それが実行中のスレッドを中断しません。

class MThread implements Runnable {
    @Override
    public void run() {
        boolean bool = Thread.currentThread().isInterrupted();
        while (!bool){
            try {
                Thread.sleep(1000);
                System.out.println("阻塞情况下"+bool);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

3.6スレッドの優先順位

  •  最も高い優先度:公共の最後の静的なint型のMAX_PRIORITY = 10;
  • 中優先度:公共の最後の静的なint型のNORM_PRIORITY = 5;
  • 最低優先順位:公共の最後の静的なint型MIN_PRIORITY = 1;
  • 設定された優先順位:公共の最終無効setPriorityを(int型newPriority)
  • 優先順位を取得します。public int型最終getPriority()
class MThread implements Runnable {
    @Override
    public void run(){
            System.out.println(Thread.currentThread().getPriority());
    }
}
public class MyThread{
    public static void main(String[] args) throws InterruptedException {
        MThread mt = new MThread();
        Thread t1 = new Thread(mt,"1") ;
        Thread t2 = new Thread(mt,"2") ;
        Thread t3 = new Thread(mt,"3") ;
        t1.setPriority(6);
        t2.setPriority(Thread.MIN_PRIORITY);
        t3.setPriority(Thread.MAX_PRIORITY);
        t1.start();
        t2.start();
        t3.start();
    }

3.7デーモンスレッド

ユーザスレッドとスレッドガード:2件のスレッドがありますJavaの

限り、任意の非デーモン現在のJVMプロセスが終了していないがあるので、ガベージコレクションをスレッドに典型的なデーモンスレッドは、デーモンが働いているはずです。最後の非デーモンスレッドが実行された場合のみ、デーモンスレッドは閉鎖されます

isDaemon()メソッドで区別することができます

class MThread implements Runnable {
    @Override
    public void run(){
            System.out.println(Thread.currentThread().isDaemon());
    }
}

 

おすすめ

転載: blog.csdn.net/weixin_43573534/article/details/90037608