4

スレッドプールのロジックを理解したいのですが、以下に単純で正しくない、完全ではない実装があります。

class ThreadPool {
    private BlockingQueue<Runnable> taskQueue;

    public ThreadPool(int numberOfThreads) {
        taskQueue = new LinkedBlockingQueue<Runnable>(10);

        for (int i = 0; i < numberOfThreads; i++) {
            new PoolThread(taskQueue).start();
        }
    }

    public void execute(Runnable task) throws InterruptedException {
        taskQueue.put(task);
    }
}


class PoolThread extends Thread {
    private BlockingQueue<Runnable> taskQueue;

    public PoolThread(BlockingQueue<Runnable> queue) {
        taskQueue = queue;
    }

    public void run() {
        while (true) {
            try {
                taskQueue.take().run();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

実行するスレッドの数が taskQueue のサイズを超えた場合、呼び出しスレッドはブロックされますか? ThreadPoolExecutor - ここで、この場合は拒否された実行ハンドラの動作であることがわかりますが、どのように機能するのかまだ理解できません。助けてくれてありがとう。

編集:

ブロッキング キューの最大サイズを 10 に設定します

4

2 に答える 2

5

レンガ職人のグループ (スレッド) が壁を作り、レンガの山 (BlockingQueue) を想像してみてください。

各レンガ職人は山からレンガを取り、配置し、別のレンガを選びます (taskQueue.take()) - 山にレンガができるまで、レンガ職人は忙しいままです。

トラックが時々到着し、積み上げられたレンガを積み上げますが、積み上げられたスペースは限られています。スペースがなければ、トラックは停車し、レンガ職人が十分な数のレンガを使い切るまで待ちます。

山に十分な数のレンガがある限り (レンガ職人の数よりも多く)、すべてのレンガ職人が作業するのに十分な数があるので安心できますが、山が空になり始めると、レンガ職人は新しいレンガが配達されるまで作業を停止する必要があります。

適切な数のれんが職人を選ぶ必要があります。少数にすると、トラックは積み上げられたスペースを待っていることがよくあります。多すぎると、ほとんどのれんがが新しいれんがを待っている間アイドル状態になります。

実装に関しては、一般に、Java はスレッドプールを提供します。独自のスレッドプールを作成することはめったにありません -

 ExecutorService threadExecutor = Executors.newFixedThreadPool( 3 );

そして、次のように呼び出します。

threadExecutor.submit(Runnable...);

タスクをキューに追加します。

于 2012-11-04T19:56:14.560 に答える
4

実行するスレッドの数が taskQueue のサイズを超えた場合、呼び出しスレッドはブロックされますか?

キューのサイズは、実行されていないタスクの数です。通常、スレッドがビジーであっても空になります。スレッドの数に一致するキューの長さは意味がなく、この時点では特別なことは何も起こりません。

ここで、この場合、拒否された実行ハンドラの作業であることがわかります

拒否ハンドラは、キューがいっぱいの場合にのみ呼び出されます。キューに制限がないため、この機能をサポートしていても呼び出されません。

ただし、制限があり、この機能をサポートしている場合、典型的な動作は例外をスローすることです。ブロックなどの他のことを実行したり、現在のスレッドにタスクを実行させたり (これは私の好みです)、タスクを無視したりできます。

私はまだそれがどのように機能するのか理解できません。

タスクをキューに offer() すると、キューがそれを受け入れることができなかった場合に false が返されます。これが発生した場合、拒否された実行ハンドラを呼び出します。

于 2012-11-04T10:30:36.480 に答える