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;
 
        }
    }

  

posted on   anpeiyong  阅读(22)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2019-03-02 SQL---MySQL数据库---聚合函数
2019-03-02 SQL---MySQL数据库---试炼

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示