线程和 TA 的静态方法们

进程:操作系统所管理的基本运行单元被看作为进程
线程:进程中独立运行的子任务看作为线程

1. 演示程序

    以下演示基于JDK1.8 API文档线程静态方法

import java.util.Arrays;
import java.util.Map;
import java.util.Optional;

/**
 * @className: ThreadStaticMethod
 * @description: static methods
 **/
public class ThreadStaticMethod {
    public static void main(String[] args) throws InterruptedException {
        init();
    }

    private static void init() throws InterruptedException {
        // 1> return current active thread
        Thread currentThread = Thread.currentThread();
        // return current thread belong to thread group
        ThreadGroup mainThreadGroup = currentThread.getThreadGroup();
        mainThreadGroup.list();

        // 2> return active thread count
        int activeCount = Thread.activeCount();
        // 3> copy activeThread of currentThreadGroup and activeThread of subThreadGroup to new array
        Thread[] copyArray = new Thread[activeCount];
        Thread.enumerate(copyArray);
        Arrays.stream(copyArray).forEach(System.out::println);

        // 4> Returns a map of stack traces for all live threads.
        Map<Thread, StackTraceElement[]> stackTraceMap = Thread.getAllStackTraces();
        stackTraceMap.forEach((key, value) -> {
            System.out.println(key);
            Arrays.stream(value).forEach(System.out::println);
        });

        // 5> return default handler at uncaught exception
        Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();
        System.out.println(handler);

        // 6> set default uncaught exception handler
        Thread.UncaughtExceptionHandler customHandle = new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                // to do something
            }
        };
        Thread.setDefaultUncaughtExceptionHandler(customHandle);
        Optional.of(Thread.getDefaultUncaughtExceptionHandler()).ifPresent(System.out::println);

        // 7> Returns true if and only if the current thread holds the monitor lock on the specified object.
        Optional.of(Thread.holdsLock(currentThread)).ifPresent(System.out::println);
        // 8> the currently executing thread to sleep
        long millis = 1_000L;
        int nanos = 100;
        Thread.sleep(millis);
        Thread.sleep(millis, nanos);

        // 9> check the thread whether has been interrupted
        Optional.of(Thread.interrupted()).ifPresent(System.out::print);
        // 10. A hint to the scheduler that the current thread is willing to yield its current use of a processor.
        Thread.yield();
        // 11> Prints a stack trace of the current thread to the standard error stream.
        // This method is used only for debugging.
        Thread.dumpStack();
    }
}

2. 补充说明

2.1 Thread.currentThread()

    获取当前线程。

2.2 Thread.activeCount()

    获取活动线程的数量。

  • ThreadGroup 线程组,一个管理线程的类,由线程组成。
  • 活动线程,started and not yet died
// A thread is alive if it has been started and has not yet died。
public final native boolean isAlive();

    活动线程的数量 nthreads,是当前线程所属线程组及各个子线程组中的活动线程总数;
    在线程对象创建时,未启动线程数自增一 nUnstartedThreads++;启动线程 start() 且正常启动时,活动线程数自增一 nthreads++,未启动线程数减一;线程启动失败 threadStartFailed() 或线程生命周期结束退出 exit() 时,活动线程数减一。

Thread.activeCount();
Thread.currentThread().getThreadGroup().activeCount();

2.3 Thread.enumerate(new Thread[length]);

    拷贝当前线程组及子线程组中的活动线程,到新的数组,即将活动线程拷贝到入参数组 Thread[] 。通常通过 Thread.activeCount() 来估算该数组的大小;
    int num = enumerate(Thread[size] array)方法返回 Thread[] 实际容纳的线程数。若想要拷贝全部的活动线程,则要严格保证 size > num,入参数组若无法容纳全部活动线程,则多余的线程会被忽略。enumerate() 方法内部也是仅拷贝活动线程(threads[i].isAlive() == true),理想情况下,activeCount 是严格满足场景的。

2.4 Thread.getAllStackTraces()

    返回堆栈跟踪的所有活动线程;Map 集合,key 为线程,value 为 StackTraceElement 数组,表示相应线程的堆栈存储

2.5 Thread.setDefaultUncaughtExceptionHandler(customHandle)

    设置默认 handle 程序处理未捕获的异常;

2.6 Thread.holdsLock(currentThread)

    校验当前对象持有监听器锁时为 true ; 对象的监听锁在同一时刻只能被一个线程持有。
演示程序

import java.util.Optional;

public class ThreadStaticHoldsLock {
    public static void main(String[] args) {
        HoldsLockThread holdsLockThread = new HoldsLockThread();
        holdsLockThread.start();
    }
}

class HoldsLockThread extends Thread {
    @Override
    public void run() {
        Optional.of(Thread.holdsLock(this)).ifPresent(System.out::println);
        synchronized (this) {
            // returns true if and only if the current thread holds the monitor lock on the specified object
            Optional.of(Thread.holdsLock(this)).ifPresent(System.out::println);
        }
    }
}

2.7 Thread.interrupted()

    验证当前线程是否被中断,线程对象调用非静态方法 interrupt() 可以主动中断当前线程。

Thread.interrupted()
Thread.currentThread().isInterrupted(true)

2.8 Thread.yield()

    线程让步,暂停执行并允许其他线程执行;示意调度程序,当前线程愿意放弃对处理器的当前使用,将和其他线程重新竞争资源;
    以下程序在 4 核处理器操作系统运行;
    一般的不使用 Thread.yield() 释放资源持有时(把 Thread.yield(); 注释掉),四个线程会先执行完毕,再开始执行另外四个线程,如输出结果一;
    当使用 Thread.yield() 时, 后四个线程也会存在在前四个线程未执行完时执行;当前四个线程,且后四个线程未进行线程让步,直到执行完毕,原先让步的线程继续执行,如输出结果二;

/**
 * @className: ThreadStaticYield
 * @description: yield() 会做出线程让步,示意执行程序已放弃持有当前资源,和其他线程重新抢占资源并执行。
 **/
public class ThreadStaticYield {
    public static void main(String[] args) {
        new YieldThread("Thread-yield-01");
        new YieldThread("Thread-yield-02");
        new YieldThread("Thread-yield-03");
        new YieldThread("Thread-yield-04");
        new NonYieldThread("Thread-non-yield-05");
        new NonYieldThread("Thread-non-yield-06");
        new NonYieldThread("Thread-non-yield-07");
        new NonYieldThread("Thread-non-yield-08");
    }
}

class YieldThread implements Runnable {

    public YieldThread(String name) {
        Thread yieldThread = new Thread(this::run, name);
        yieldThread.start();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().toString() + "executing!");
        for (int i = 0; i < 100; i++) {
            System.out.print("");
            Thread.yield();
        }
        System.out.println(Thread.currentThread().toString() + "executed!");
    }
}

class NonYieldThread implements Runnable {

    public NonYieldThread(String name) {
        Thread nonYieldThread = new Thread(this::run, name);
        nonYieldThread.start();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().toString() + "executing!");
        for (int i = 0; i < 100; i++) {
            System.out.print("");
        }
        System.out.println(Thread.currentThread().toString() + "executed!");
    }
}

输出结果一(注释程序中的 Thread.yield() 方法)

Thread[Thread-yield-01,5,main]executing!
Thread[Thread-yield-03,5,main]executing!
Thread[Thread-yield-02,5,main]executing!
Thread[Thread-yield-02,5,main]executed!
Thread[Thread-yield-03,5,main]executed!
Thread[Thread-yield-01,5,main]executed!
Thread[Thread-yield-04,5,main]executing!
Thread[Thread-yield-04,5,main]executed!
Thread[Thread-non-yield-05,5,main]executing!
Thread[Thread-non-yield-06,5,main]executing!
Thread[Thread-non-yield-06,5,main]executed!
Thread[Thread-non-yield-07,5,main]executing!
Thread[Thread-non-yield-07,5,main]executed!
Thread[Thread-non-yield-08,5,main]executing!
Thread[Thread-non-yield-08,5,main]executed!
Thread[Thread-non-yield-05,5,main]executed!

输出结果二

Thread[Thread-yield-01,5,main]executing!
Thread[Thread-yield-02,5,main]executing!
Thread[Thread-yield-03,5,main]executing!
Thread[Thread-yield-04,5,main]executing!
Thread[Thread-non-yield-05,5,main]executing!
Thread[Thread-non-yield-05,5,main]executed!
Thread[Thread-yield-02,5,main]executed!
Thread[Thread-non-yield-06,5,main]executing!
Thread[Thread-non-yield-06,5,main]executed!
Thread[Thread-yield-01,5,main]executed!
Thread[Thread-non-yield-07,5,main]executing!
Thread[Thread-non-yield-07,5,main]executed!
Thread[Thread-non-yield-08,5,main]executing!
Thread[Thread-non-yield-08,5,main]executed!
Thread[Thread-yield-03,5,main]executed!
Thread[Thread-yield-04,5,main]executed!

附:官方文档

在线文档:https://docs.oracle.com/javase/8/docs/api/
离线文档:https://www.oracle.com/java/technologies/javase-jdk8-doc-downloads.html

Power By niaonao

©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页