【Java】多线程处理

結束

    • プロセスとスレッドの違いは重要

 

    マルチスレッドの意義は独立に動かし、かつ同じプロセス内のメモリ空間を共有することができること

线程是指一个独立的执行路径。

    • プログラムを実行する処理の最小単位

アプリはメインスレッドという単一スレッドで動く
しかし単一スレッドでは、ネットワーク通信時などで、アプリ利用者は次の操作を通信終了まで待たないといけなくなる
スレッドが複数ある(=マルチスレッド)と、ネットワーク通信はバックグラウンドで他のスレッドが実行し、通信中でもメインスレッドで処理を並行して実行することができる

“プロセス”是指一个过程。

    • プログラムのインスタンスそのもの

 

    • 新プロセス起動にはCPUとメモリの割り当てが必要

プロセスは1つ以上のスレッドを持つ

1対1..n(1以上のn)関係

UML表記では、プロセス側から見てスレッドは 1…n 個

过程 1
|
线程 1..n

内存组织

プロセス:Main関数で動いているプログラム
プロセスという大きい箱のなかにスレッドがある

Main関数は1スレッドでうごいている
あるプロセスは1個以上のスレッドを持たないといけない(mainスレッド)

1111_1.png

线程的特征 – 独立性和内存空间共享

    • スレッド同士はお互い独立して動く

1個止まってもバックグラウンドで動くスレッドは独立して稼働
メインスレッドで通信処理をしていると通信して答えが返ってくる間止まってしまうので、
その間も処理させるために並列処理させる

マルチスレッドで3スレッド立ち上げたときに1プロセス内にある理由はメモリ空間を共有するため

Mainスレッド内に変数を定義したら全スレッドがアクセスできる

public class Main {
    String hoge = "hoge"; //この変数は共有される
    public static void main(String[] args) {
        new Main().run();
    }
    private void run(){
        while (true) {
            System.out.println("1"); //Mainスレッド
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("2");
        }
    }
}

创建和执行线程

    • Threadクラスを継承

 

    Runnableインターフェース実装

继承 Thread 类

    • Thread派生クラスでは絶対runメソッド(呼び出すエンドポイント)をオーバーライドする

 

    • Thread派生クラスのメソッド

currentThread:実行中スレッド取得

getId:スレッドID取得

isAlive:スレッド生存確認

join:スレッド終了するまでms待機

setPriority:優先順位設定

sleep:スレッド実行休止

public class MyThread extends Thread {
//スレッド実処理はThread派生クラス
  @Override
  public void run() {
    for (var i = 0; i < 30; i++) {
      //getNameでスレッド名取得
      System.out.println(this.getName() + ": " + i);
    }
  }
}
public class ThreadBasic {

  public static void main(String[] args) {
    //インスタンス化しスレッド生成
    var th1 = new MyThread();
    var th2 = new MyThread();
    var th3 = new MyThread();
    //startメソッドでスレッド開始
    th1.start();
    th2.start();
    th3.start();
  }
}

实现Runnable接口

    • 継承ではなく実装(implements Runnable)

関数型インターフェースである

スレッド名に直接アクセスできないのでThread.currentThread()静的メソッドで現スレッドを取得し、getNameメソッドにアクセス
インスタンス化にはThreadコンストラクターにRunnable実装クラスのインスタンスを渡す

public class MyRunner implements Runnable {
  //スレッド実処理
  @Override
  public void run() {
    for (var i = 0; i < 30; i++) {
      System.out.println(Thread.currentThread().getName() + ": " + i);
    }
  }
}
public class RunnableBasic {

  public static void main(String[] args) {
    //スレッド生成
    var th1 = new Thread(new MyRunner());
    var th2 = new Thread(new MyRunner());
    var th3 = new Thread(new MyRunner());
    //スレッド開始
    th1.start();
    th2.start();
    th3.start();
  }
}
bannerAds