ホームページ  >  記事  >  Java  >  Javaスレッドプールの構築方法の実装方法

Javaスレッドプールの構築方法の実装方法

転載
2023-04-19 15:13:07732ブラウズ

1. はじめに

並行プログラミングを実現するために、プロセスの概念が導入されました。プロセスはオペレーティング システムのタスクに相当します。複数のプロセスが同時にタスクを実行するため、並行プログラミングが実現され、より高速な実行が可能になります。

しかし、プロセスは十分に軽量ではないため、プロセスの作成と破棄によって消費されるリソースは無視できません。プロセスの数が多くない場合、これらのリソースの消費は許容されますが、プロセスの作成と破棄が頻繁に行われる場合は許容されます。それは多大な出費です。 #########私たちは何をすべきか?

この問題を解決するために、人々はより軽量なツール スレッドを導入しました。

スレッドは軽量プロセスとも呼ばれます。その作成と破棄では、プロセスよりも少ないリソースが消費されます。しかし、タスクの数が多く、マルチスレッドが頻繁な作成と破棄に耐えられない場合はどうなるでしょうか?このとき、スレッド プールが問題を解決します!

2. スレッド プールとは何ですか?

スレッド プールは、Java 文字列定数プールに似ています。

スレッドを使用する場合とスレッドを使用しない場合

スレッドを使用する場合は、プールから直接スレッドを取得するだけです。
  • スレッドが使用されていない場合は、このスレッドをプールに入れてください
  • 仕事を見つけるプロセスはおそらく次のようなものであることは誰もが知っています。

履歴書の提出
  • 筆記試験
  • 面接
  • offer
  • 面接に至った後は、2 つの状況があります。

合格した場合、企業はあなたに電話して通知し、オファーを送ります
  • 合格した場合、企業は通常は連絡しません。失敗したことは伝えましたが、会社があなたを「人材予備群」に入れる可能性があるため、失敗したことはまったく伝えませんでした。
  • 会社が 50 人を募集しており、秋の採用期間中に 50 人にオファーを送ったとします。しかし実際に報告に来たのは35人だけだった。このとき、残りの15人は人材予備プールから直接15人を釣り上げて直接オファーを出します。
もしかしたら少し時間が経った頃かもしれませんが、突然会社から採用の連絡が来たのですが、来ませんか?この操作は、プールからスレッドを直接使用することと同じです。

これは、就職活動の例を使用して、スレッド プールがおそらく何を意味するのかを説明するためです。

3. スレッド プール構築メソッド ThreadPoolExecutor の構築メソッドのパラメータは何を意味しますか?

「Alibaba Java 開発マニュアル」では、スレッド リソースはスレッド プールを通じて提供する必要があり、スレッドの作成をアプリケーションに表示することは許可されていないと指摘されています。スレッドの数はより標準化され、開発は合理的に制御されますが、スレッドの詳細な管理はスレッド プールに引き渡され、リソースのオーバーヘッドが最適化されます。

「ThreadPoolExecutor」クラスは、スレッド プールを使用するために Java 標準ライブラリによって提供されるクラスのセットです。

ThreadPoolExecutor には 4 つの構築メソッドがあります。それぞれに異なるパラメーターが含まれており、異なるシナリオで使用されます。

最もパラメータの多い構築方法を紹介します。
ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor (
int corePoolSize,
int maximumPoolSize ,
long keepAliveTime ,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
 ThreadFactory threadFactory,
 RejectedExecutionHandler handler
 )


1.corePoolSize コア スレッドの数Javaスレッドプールの構築方法の実装方法

2.maximumPoolSize スレッドの最大数

コア スレッドの数についてスレッドの最大数は正確には理解できませんが、これは出勤する従業員の例です。

コアスレッドの数は、会社の正式な従業員であり、しばらくの間釣りをすることができます。見つかっても解雇されません。 (スレッドプール内の何もしなくても破壊されないスレッドに相当)

スレッドの最大数は社内の正社員と派遣社員の数ですが、ここでの派遣社員は一定のレベルに達したらクビにする時が来ました。 (スレッド プール内のスレッドが破棄されるのと同じです)

3.keepAliveTime は、一時ワーカーが釣りできる時間を記述します。

4.unit は時間の単位であり、keepAliveTime の単位です。 。

5.workQueue ブロッキング キューは、スレッド プールによって実行されるタスクを編成します。

6.threadFactory スレッド作成メソッド。このパラメータを使用して、さまざまなスレッドの作成メソッドを設定します

7.RejectedExecutionHandler ハンドラーの拒否戦略。タスクキューがいっぱいになって新しいタスクが来た場合、このときどうすればよいでしょうか?

(1): 最新のタスクは不要

(2): 最も古いタスクは不要

(3): ブロック待ち

( 4) 振り子を開く: 例外をスローします

ThreadPoolExecutor は使用がより複雑であるため、最大 7 つのパラメーターがあります。標準ライブラリは、この目的のためにプログラマに一連の追加クラスを提供します。これは、ThreadPoolExecutor の別のカプセル化層に相当します。

1.newFixedThreadPool

: 固定数のスレッドを持つスレッド プールを作成します。

 ExecutorService Service1   =  Executors.newFixedThreadPool (20);
2.newCachedThreadPool

: 変数番号を使用してスレッド プールを作成します。

ExecutorService Service2   = Executors.newCachedThreadPool ();
3.newSingleThreadExecutor

: 1 つのスレッドのみを使用してスレッド プールを作成します。

ExecutorService Service3  = Executors.newSingleThreadExecutor ();
4.newScheduledThreadPool

: 遅延時間を設定できるスレッドプールを作成します。

ExecutorService Service4   = Executors.newScheduledThreadPool (20);
4. スレッド プールのシミュレーションと実装
模拟实现一个线程池的核心操作:
.:将任务加到线程池中--submit。
.:使用Worker类描述一个工作线程,Runnable来描述一个任务。
.:创建一个BlockingQueue阻塞队列组织所有任务。
.:每个Worker要做的事情就是不停的从阻塞队列里获取任务并执行。
.:指定线程池中的线程最大数目,如果超过这个数目就不要再继续创建线程了。

コードの実装:

我们创建一个线程池并让它不停的创建进程打印hello

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Created with IntelliJ IDEA.
 *
 
 * @Description: 模拟实现线程池的使用
 */
public class ThreadDemo0327_2 {
    public static void main (String[] args) throws IOException, InterruptedException {
        ThreadPoll threadPoll=new ThreadPoll ();
        for (int i = 0 ; i <10  ; i++) {
            threadPoll.submit (new Runnable () {
                @Override
                public void run () {
                    System.out.println ("hello");
                }
            });
        }
    }
}

class  Worker extends  Thread{
    public   BlockingQueue<Runnable> queue=null;
    public Worker(BlockingQueue<Runnable> queue){
        this.queue=queue;
    }

    @Override
    public void run () {
        //工作线程的具体逻辑
        //需要从阻塞队列中取任务.
        while (true){
            try {
                Runnable command=queue.take ();
                //通过run来执行具体任务
                command.run ();
            }catch (InterruptedException e){
                e.printStackTrace ();
            }
        }
    }
}

class  ThreadPoll{
    //包含一个阻塞队列,用来组织任务
  public   BlockingQueue<Runnable> queue=new LinkedBlockingQueue<> ();

    //这个list就用来存放当前的工作线程.
    public  List<Thread> works=new ArrayList<> ();

    public  int MAX_WORKER_COUNT=10;

    //通过这个方法,把任务加入到线程池中
    //submit不光可以把任务放到阻塞队列中,也可以负责创建线程
    public  void submit(Runnable command) throws IOException, InterruptedException {
        if(works.size ()<MAX_WORKER_COUNT){
            //如果当前工作线程的数量不足线程数目上线,就创建出新的线程
            //工作线程就专门找一个类完成
            //worker内部要哦能够取到队列的内容,就要把这个队列实例通过worker的构造方法传过去
            Worker worker=new Worker (queue);
            worker.start ();
            works.add (worker);
        }
        queue.put (command);
    }
}

运行效果:

可以看到,打印了10个hello。

Javaスレッドプールの構築方法の実装方法

以上がJavaスレッドプールの構築方法の実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。