JavaSE---线程控制
1 | <br><br><br> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | /** * * 当线程在系统内运行时,程序无法 准确控制 线程的轮换执行,可以通过 一些机制 保证线程的协调运行; * * 实现机制: * 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实例的锁定后,才可以执行 被唤醒的线程; * */ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | 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 ; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2019-03-02 SQL---MySQL数据库---聚合函数
2019-03-02 SQL---MySQL数据库---试炼