ご存知のとおり、スレッドを操作するには、スレッドの API メソッドを熟知する必要があります。マルチスレッドを開始して車を停止できなくなった場合、クックを停止することになります。ここでは、基本的な API の使用法をいくつか紹介します。スリープ、参加、譲歩、割り込みを含みます。
sleep、現在のスレッドをしばらくスリープさせます。Thread.sleep (ミリ秒) をネイティブに使用すると、割り込み例外がスローされます。コード内にローテーション トレーニング メカニズムがある場合、この方法により CPU 100% の問題を防ぐことができます。while(true) にスリープを追加すると、CPU 消費量が少なくとも 80% 削減されます。基本的には自作ツールを使用します。JUC は変更をサポートしているため、毎回例外をキャッチする必要はありません。
public class SleepUtils {
public static void sleep(int second){
try {
TimeUnit.SECONDS.sleep(second);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
joinは、呼び出し元の join スレッドが終了して実行を継続するのを待ち、通常はスレッド間通信に使用されます。たとえば、t1 は水を沸騰させ、t2 はお茶を作ります。明らかに、t2 は開始する前に t1 が終了するまで待つ必要があるため、t1.join() を使用してそれを実現できます。
参加コードの表示
@Slf4j
public class Thread03 {
public static int i =0;
public static void main(String[] args) throws Exception{
Thread t1 = new Thread(()->{
log.info("t1 start");
SleepUtils.sleep(1);
i++;
});
t1.start();
t1.join();//必须等t1执行完,否则可能i=0
log.info("t1 start i={}",i);
}
}
イールドとは、CPU の使用権を一時的に放棄し、他のスレッドが最初に実行できるようにすることを指します。これは、ホット データとコールド データを処理するときに使用できます。たとえば、スレッド t1 と t2 の両方がチケットの販売を処理しており、表紙に美しい女性が登場すると t2 のアクセス数が増える可能性がありますが、実際には、t1 と t2 は CPU タイム スライスを占有するために同時に実行されており、Java レベルでは、スレッド t1 が Thread.yield() を使用して、t2 の単位時間あたりの処理をより強力にすることができます。
割り込みはスレッドを中断することです。実行中のスレッドを中断しても、サービスは中断されず、中断後のロジックが実行され続け、中断後に true としてマークされる場合の 2 つのケースがあります。ブロックされたスレッドを中断すると、sleep wait join によってサービスが中断され、中断後も中断フラグは false のままになります。
割り込みコードを見ると、この例はスレッドの2段目の割り込みであり、実行時割り込みとブロック時割り込みが判定される。そして割り込み識別の処理。
@Slf4j
public class ThreadInterrupt02 {
public static void main(String[] args) {
/**
* 有一个监控线程,如果出现异常则停止,如果未出现继续监控
*/
Monitor monitor = new Monitor();
monitor.start();
SleepUtils.sleep(5);//休眠5s后执行打断操作
monitor.stop();
}
}
@Slf4j
class Monitor {
private Thread monitor;
public void start(){
monitor = new Thread(()->{
while (true){
log.info("monitor 正在监控中");
//判断当前线程上次是否被打断,如果打断直接退出
if (Thread.currentThread().isInterrupted()) {
log.info("monitor 被打断");
break;
}
//如果没退出,休眠2秒继续执行,此过程可能会打断
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
log.info("睡眠被打断");
e.printStackTrace();
Thread.currentThread().interrupt();//如果在睡眠过程被打断,标识仍为false,不会break,所以这里二次打断
}
}
});
monitor.start();
}
public void stop(){
monitor.interrupt();
log.info("线程执行打断");
}
}