【Java】Thread深入學習

本篇文章將介紹Thread類相關方法,以及一些重要概念及應用。JDK提供了直觀觀察線程狀態的工具,在學習線程的過程中,可以使用jconsole命令打開Java監視和管理控制檯觀察線程運行狀態。

在這裏插入圖片描述

1. setDaemon()

守護線程: 當子線程被設置爲守護線程時,父線程一旦進入DEAD狀態,守護線程也立即進入DEAD狀態。示例:

package com.juc;

/**
 * 守護線程: 當被設置爲父線程的守護線程時,父線程一旦銷燬,子線程也立即銷燬。
 * 1. setDaemon(boolean on)必須在線程變成Runnable狀態前執行
 * 2. 爲維持長連接,需要心跳包,可以將心跳包設置爲守護線程,主線程一旦銷燬,即不用再發送心跳包維持狀態
 */

public class ThreadDaemon {

    public static void main(String[] args) {

        long interval = 2_000L;

        Thread daemonThread = new Thread(() -> {
            Thread innerDaemonThread = new Thread(() -> {
                while (true) {
                    try {
                        Thread.sleep(interval);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " is alive");
                }
            }, "innerDaemonThread");
            innerDaemonThread.setDaemon(true);
            innerDaemonThread.start();

            while (true) {
                try {
                    Thread.sleep(interval);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " is alive");
            }
        }, "daemonThread");

        daemonThread.setDaemon(true);
        daemonThread.start();

        try {
            Thread.sleep(4_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " thread is dead");
    }


}

在這裏插入圖片描述

2. join()

當線程對象使用join()方法後,當前線程所在的父線程將處於BLOCKED狀態直到當前線程任務執行完畢。示例:

package com.juc;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.IntStream;

/**
 * join() 子線程在join()時,父線程會進入blocked狀態,直到子線程完成任務,父線程恢復正常
 *
 * Thread.currentThread().join() main會等待main,死循環
 */
public class ThreadJoin {

    public static void main(String[] args) {

        List<Thread> threadList = new ArrayList<>();

        for (int i = 1; i < 4; i++) {
            threadList.add(new ChildThread("childThread" + i));
        }

        threadList.forEach(
                thread -> {
                    thread.start();
                    try {
                        thread.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
        );

        System.out.println("All done.");

    }

}

class ChildThread extends Thread {

    private String threadName;

    public ChildThread(String threadName) {
        this.threadName = threadName;
    }

    @Override
    public void run() {
        IntStream.range(1, 10).forEach( i -> {
            Optional.of(Thread.currentThread().getName() + " " + i).ifPresent(System.out::println);
        });
    }
}

在這裏插入圖片描述

3. interrupt()

線程在執行過程中可以被中斷,調用interrupted()查看是否被中斷。

package com.juc;

import java.util.Optional;
import java.util.stream.IntStream;

public class ThreadInterrupt {

    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            IntStream.range(1, 10).forEach(
                    i -> {
                        try {
                            Thread.sleep(1_000);
                        } catch (InterruptedException e) {
                             System.out.println("線程被中斷 ");
                        }
                        Optional.of(i).ifPresent(System.out::println);
                    }
            );
        }, "thread");

        thread.start();
        try {
            Thread.sleep(2_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();

    }

}

在這裏插入圖片描述

4. setPriority()、線程優先級

package com.juc;

import java.util.Optional;
import java.util.stream.IntStream;

/**
 * @Description Thread類相關的API
 */
public class ThreadAPI {

    public static void main(String[] args) {
        Thread thread1 = new Thread( ()-> {
            printInfo();
        }, "thread1");
        Thread thread2 = new Thread( ()-> {
            printInfo();
        }, "thread2");
        Thread thread3 = new Thread( ()-> {
            printInfo();
        }, "thread3");

        // priority: 優先級的設定有時並無意義,線程能否進入運行狀態取決於CPU是否有空閒的時間片
        thread1.setPriority(Thread.MAX_PRIORITY);
        thread2.setPriority(Thread.NORM_PRIORITY);
        thread3.setPriority(Thread.MIN_PRIORITY);

        thread1.start();
        thread2.start();
        thread3.start();
    }

    // id,name: 一般來說,我們創建的第一個線程id爲11,前9個是必須線程,第10個是main
    private static void printInfo() {
        Thread c_thread = Thread.currentThread();
        System.out.printf("============%s id: %s===============\n", c_thread.getName(), c_thread.getId());
        IntStream.range(1, 10).forEach(i -> {
            Optional.of(c_thread.getName() + " " + i).ifPresent(System.out::println);
        });
    }

}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章