JavaSE---线程控制




 
/**
     * 
     *      当线程在系统内运行时,程序无法 准确控制 线程的轮换执行,可以通过 一些机制 保证线程的协调运行;
     *
     *      实现机制:
     *          1、Object的wait(), notify(), notifyAll() ,必须 由 同步监视器 调用;
     *              适用 synchronized 情形;
     *
     *              wait:
     *                  导致 当前线程等待,直到 其他线程 调用 该同步监视器的notify、notifyAll 唤醒 该线程;
     *
     *                  调用wait方法,当前线程 会释放 对 该同步监视器的锁定;
     *
     *                  wait三种形式:
     *                      wait():
     *                          当前线程 无时间限制,直到 其他线程 通知;
     *                      wait(long timeout):
     *                      wait(long timeout, int nanos):
     *                          带毫秒(或 带毫秒+微妙);
     *                          当前线程 等待 指定时间后 自动苏醒;
     *
     *              notify:
     *                  唤醒 在此同步监视器 上等待的单个线程;
     *                      如果 此同步监视器 有多个线程 等待,则会随机唤醒其中一个;
     *
     *                  只有 当前线程 放弃 对该同步监视器的锁定后,才能执行被唤醒的线程;
     *
     *              notifyAll:
     *                  唤醒 在此同步监视器 上等待的所有线程;
     *
     *                  只有 当前线程 放弃 对该同步监视器的锁定后,才能执行被唤醒的线程;
     *
     *         2、JDK提供的 Condition,由 指定Lock实例关联的Condition实例 调用;
     *              适用 JDK的 Lock情形;
     *
     *              Condition将 同步监视器方法(wait、notify、notifyAll) 分解成 截然不同的对象;
     *              将 Condition对象 与 Lock对象 组合使用;
     *              Condition对象 实质上 被绑定到 一个Lock实例上,要获取指定Lock实例的Condition实例,调用Lock.newCondition();
     *
     *              await():
     *                  导致 当前线程 等待,直到其他线程 调用 该Condition实例的signal 或 signalAll 唤醒 该线程;
     *
     *                  Condition实例 对应的Lock实例 自动释放;
     *
     *              signal():
     *                  唤醒 在此Lock实例 上 等待的单个线程;
     *                      如果 此Lock实例有多个重新,则随机唤醒其中一个线程;
     *
     *                  只有 当前线程 释放 对该Lock实例的锁定后,才可以执行 被唤醒的线程;
     *
     *              signalAll();
     *                  唤醒 在此Lock实例 上 所有等待的线程;
     *
     *                  只有 当前线程 释放 对该Lock实例的锁定后,才可以执行 被唤醒的线程;
     *
     */

  

public static void main(String[] args) throws InterruptedException {

        Thread.currentThread().setName("mainThread");

//        joinTest();

//        sleepTest();

//        yieldTest();

//        threadPriorityTest();

//        threadGroupTest();

        exceptionHandlerTest();

//        threadLoaclTest();

    }

    private static void threadLoaclTest() {

//        ThreadLocal
    }

    private static void exceptionHandlerTest() {

        Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

        SubThread subThread = new SubThread();
        subThread.setName("SubThread");
        subThread.start();
    }


    static class MyExceptionHandler implements Thread.UncaughtExceptionHandler{
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("MyExceptionHandler uncaughtException... ");
            System.out.println("currentThread:"+ t.getName());
            System.out.println("e:"+ e);
        }
    }

    /**
     * 每个Java线程都是 某个线程组 的成员;
     *
     * 线程组 提供一种机制,使得多个线程 集于 一个对象内,对 它们进行整体操作;
     *
     * 线程只能属于一个线程组,并且当线程产生后不能改变它所属的线程组,直到 该线程死亡;
     *
     * 默认情况下,子线程与创建它的父线程 处于同一个 线程组内;
     *
     * 【线程组内的线程异常处理】
     *      JDK5开始,Java增强了 线程的异常处理,如果线程执行过程中出现 异常,
     *          JVM会在结束该线程之前 查找 是否有对应的java.lang.Thread.UncaughtExceptionHandler对象,
     *          如果找到,调用java.lang.Thread.UncaughtExceptionHandler对象的uncaughtException处理异常;
     *
     *      java.lang.Thread.UncaughtExceptionHandler
     *          Thread类的一个内部公共静态接口;
     *          {
     *              // t:出现异常的线程,e:该线程抛出的异常
     *              void uncaughtException(Thread t, Throwable e);
     *          }
     *
     *      异常处理器设置:
     *          public class Thread implements Runnable{
     *
     *              public interface UncaughtExceptionHandler {
     *                  void uncaughtException(Thread t, Throwable e);
     *              }
     *
     *              private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
     *              private ThreadGroup group;
     *
     *              public UncaughtExceptionHandler getUncaughtExceptionHandler() {
     *                  return uncaughtExceptionHandler != null ? uncaughtExceptionHandler : group;
     *              }
     *
     *              // Dispatch an uncaught exception to the handler. 转发uncaught exception;
     *              // This method is intended to be called only by the JVM. 由JVM调用;
     *              private void dispatchUncaughtException(Throwable e) {
     *                  getUncaughtExceptionHandler().uncaughtException(this, e);
     *              }
     *
     *              // 为该线程类的 所有线程实例 设置 默认的异常处理器;
     *              public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {}
     *
     *              // 为指定线程实例 设置 异常处理器
     *              public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {}
     *
     *          }
     *
     *
     *      ThreadGroup实现了java.lang.Thread.UncaughtExceptionHandler,所以 每个线程所属的线程组 将会作为默认的异常处理器;
     *          public class ThreadGroup implements Thread.UncaughtExceptionHandler{
     *              public void uncaughtException(Thread t, Throwable e) {
     *                  Thread.UncaughtExceptionHandler ueh = Thread.getDefaultUncaughtExceptionHandler();
     *              }
     *          }
     *
     */
    private static void threadGroupTest() {
        System.out.println(Thread.currentThread().getName() + " ThreadGroup: " + Thread.currentThread().getThreadGroup().getName());

        SubThread subThread = new SubThread();
        subThread.setName("SubThread");
        subThread.start();

        /**
         * mainThread ThreadGroup: main
         * SubThread Priority : 5
         * SubThread---running
         * SubThread---running
         * SubThread---running
         * SubThread ThreadGroup: main
         */
    }

    /**
     * 每个线程 默认的优先级 :
     *      与 创建它的父线程 具有相同的优先级;
     *
     * 线程优先级范围 1 到 10;
     *
     * Java采用的是一种简单、固定的调度法,即固定优先级调度;
     */
    private static void threadPriorityTest() {
        System.out.println(Thread.currentThread().getName() + " Priority : " + Thread.currentThread().getPriority());

        SubThread subThread = new SubThread();
        subThread.start();

        /**
         * mainThread Priority : 5
         * Thread-0 Priority : 5
         */
    }

    /**
     * yield :
     *      让当前执行的线程暂停,但 不进入阻塞状态,直接进入就绪状态;
     *
     *      yield只是 让当前执行线程暂停一下,让系统的线程调度器重新调度;
     *
     *      当 某个线程调用了yield后,只有 优先级与当前线程相同(或 优先级高于当前线程的就绪状态的线程) 才会获得执行机会;
     */
    private static void yieldTest() {
        Thread.yield();
    }

    /**
     * sleep:
     *      sleep 将当前执行的线程 进入阻塞状态,直到 过了 阻塞时间 才会进入 就绪状态;
     *      其他线程将会抢CPU资源,不关心 线程优先级;
     *
     */
    private static void sleepTest() throws InterruptedException {
        for (int i = 0; i < 4; i ++){
            if (i == 3){
                Thread.sleep(5000);
            }
            System.out.println(Thread.currentThread().getName() + ": i=" +i);
        }
    }

    /**
     * join:
     *      当前执行线程 调用 其他线程的join方法,当前线程 进入阻塞状态,直到 其他线程执行完成;
     */
    static void joinTest() throws InterruptedException {

        SubThread subThread = new SubThread();
        subThread.setName("SubThread");

        //join
        for (int i = 0; i < 5; i++){
            System.out.println(Thread.currentThread().getName() + "---running");
            if (i == 3){
                subThread.start();
                System.out.println(subThread.getName() + "---join");
                subThread.join();
            }
        }

        /**
         * mainThread---running
         * mainThread---running
         * mainThread---running
         * mainThread---running
         * SubThread---join
         * SubThread Priority : 5
         * SubThread---running
         * SubThread---running
         * SubThread---running
         * mainThread---running
         */
    }

    static class SubThread extends Thread{

        @Override
        public void run() {

            System.out.println(Thread.currentThread().getName() + " Priority : " + Thread.currentThread().getPriority());

            for (int i = 0; i< 3; i++){
                System.out.println(this.getName() + "---running");
            }

            System.out.println(Thread.currentThread().getName() + " ThreadGroup: " + Thread.currentThread().getThreadGroup().getName());

            int i = 1/0;

        }
    }

  

posted on 2022-03-02 10:43  anpeiyong  阅读(20)  评论(0编辑  收藏  举报

导航