1.マルチスレッド作成方法
1.スレッドクラスを継承します
//继承Thread类来创建线程
public class ThreadTest {
public static void main(String[] args) {
//设置线程名字
Thread.currentThread().setName("thread");
MyThread myThread = new MyThread();
myThread.setName("子线程:");
//开启线程
myThread.start();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName() + i);
}
}
}
class MyThread extends Thread{
//重写run()方法
public void run(){
for(int i=0;i<10; i++){
System.out.println(Thread.currentThread().getName() + i);
}
}
}
2.Runableインターフェースを実装します
//实现Runnable接口
public class RunnableTest {
public static void main(String[] args) {
//设置线程名字
Thread.currentThread().setName("thread:");
Thread thread = new Thread(new MyRunnable());
thread.setName("子线程:");
//开启线程
thread.start();
for(int i=0; i<10;i++){
System.out.println(Thread.currentThread().getName() + i);
}
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i=0; i<10; i++) {
System.out.println(Thread.currentThread().getName() + i);
}
}
}
3. Callableインターフェイスを実装します(コールバック付き)
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
//实现Callable接口
public class CallableTest {
public static void main(String[] args) {
//执行Callable 方式,需要FutureTask 实现实现,用于接收运算结果
FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyCallable());
new Thread(futureTask).start();
//接收线程运算后的结果
try {
Integer sum = futureTask.get();
System.out.println(sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i=0; i<10; i++) {
sum += i;
}
return sum;
}
}
4.スレッドプールの作成
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//线程池实现
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
ThreadPool threadPool = new ThreadPool();
for(int i =0;i<5;i++){
//为线程池分配任务
executorService.submit(threadPool);
}
//关闭线程池
executorService.shutdown();
}
}
class ThreadPool implements Runnable {
@Override
public void run() {
for(int i=0 ;i<10;i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
2.共通スレッドプール
1. newFixedThreadPool
は、ワーカースレッドの数を指定するスレッドプールを作成します。タスクが送信されるたびに、ワーカースレッドが作成されます。ワーカースレッドの数がスレッドプールの初期最大数に達すると、送信されたタスクはプールキューに格納されます。
newFixedThreadPoolは、典型的で優れたスレッドプールであり、プログラムの効率を向上させ、スレッド作成時のオーバーヘッドを節約するスレッドプールの利点があります。ただし、スレッドプールがアイドル状態の場合、つまりスレッドプールに実行可能なタスクがない場合、スレッドプールはワーカースレッドを解放せず、特定のシステムリソースを占有します。
2. newCachedThreadPool
は、キャッシュ可能なスレッドプールを作成します。スレッドプールの長さが処理のニーズを超える場合、アイドル状態のスレッドを柔軟にリサイクルできます。リサイクル可能なスレッドがない場合は、新しいスレッドが作成されます。
このタイプのスレッドプールの特徴は次のとおりです。
(1)作成されるワーカースレッドの数にほとんど制限がないため(実際には制限があり、数はInterger。MAX_VALUEです)、スレッドをスレッドに追加できます。柔軟にプールします。
タスクがスレッドプールに長時間送信されない場合、つまり、ワーカースレッドが指定された時間(デフォルトは1分)アイドル状態の場合、ワーカースレッドは自動的に終了します。終了後、新しいタスクを送信すると、スレッドプールはワーカースレッドを再作成します。
(2)newCachedThreadPoolを使用する場合は、タスク数の制御に注意する必要があります。そうしないと、同時に実行されるスレッドの数が多いため、システム障害が発生する可能性があります。
3. newSingleThreadExecutor
は、シングルスレッドのエグゼキューターを作成します。つまり、タスクを実行するために一意のワーカースレッドのみを作成し、タスクを実行するために一意のワーカースレッドのみを使用して、すべてのタスクが指定された順序(FIFO、LIFO、優先度)。このスレッドが異常終了した場合は、順次実行するために別のスレッドに置き換えられます。シングルワーカースレッドの最大の特徴は、さまざまなタスクの順次実行を保証でき、常に複数のスレッドがアクティブにならないことです。
4. newScheduleThreadPool
は、固定長のスレッドプールを作成し、タイミングと定期的なタスクの実行をサポートし、タイミングと定期的なタスクの実行をサポートします。
3.スレッドプールの7つのコアパラメータ
1.corePoolSize(コアスレッドの数)
2.maxPoolSize(スレッドの最大数)
3.keepAliveTime(アイドル回復時間)
4.unit(回復時間単位)
5.workQueue(タスクキュー)
6.threadFactory(スレッドファクトリ、スレッドの作成に使用され、通常はデフォルトのスレッドファクトリ)
7.ハンドラー(拒否戦略)
execute(()メソッドを呼び出してリクエストタスクを追加すると、スレッドプールは次の判断を下します::
スレッド作成タスクの数がコアスレッドの数より少ない場合はcorePoolSizeが直接作成されて実行され、スレッド作成タスクの数がコアスレッドの数よりも多い場合はタスクキューworkQueueに追加されます。
(一般的なタスクキューには制限付きキューがあります: 1.ArrayBlockingQueue、2.SynchronousQueue、
無制限キュー:1。LinkedBlockingQueue、まだ詳細はありません。)待つ、
タスクキューもいっぱいの場合は、スレッドの最大数maxPoolSizeより大きいかどうかを確認します。キューがいっぱいで、実行中のスレッドの数がnaximumPoolSize未満の場合でも、非コアスレッドを作成する必要があります。タスクをすぐに実行するには、スレッドの最大数よりも多い場合は、拒否ポリシーハンドラーを実行します
(4つの拒否戦略があります:
1. CallerRunsPolicy:このストラテジーは、現在のタスクの追加を再試行し、成功するまでexecute()メソッドを繰り返し自動的に呼び出します。
2. AbortPolicy:拒否されたタスクを破棄し、例外をスローします。
3. DiscardPolicy:異常な情報なしに、拒否されたタスクを直接サイレントに破棄します。
4. DiscardOldestPolicy:拒否されたタスクを破棄せずに、キューで最も長く待機していたスレッドを破棄してから、拒否されたタスクをキューに追加します。
)そうでない場合は、作成して実行します。スレッドがタスクを完了すると、キューから次のタスクを取得して実行します。スレッドが特定の時間(keepAliveTime))を超えて何の関係もない場合、スレッドプールは判断します。現在実行中のスレッドの数がcorePoolSizeより大きい場合、このスレッドは停止します。したがって、スレッドプールのすべてのタスクが完了すると、最終的にはcorePoolSizeのサイズに縮小されます。