当前位置:首页 » 《随便一记》 » 正文

JavaEE 初阶篇-多线程属性和方法

11 人参与  2024年03月29日 13:25  分类 : 《随便一记》  评论

点击全文阅读


?博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞?收藏⭐评论✍

文章目录

        1.0 创建线程对象并命名

        2.0 线程属性

        2.1 线程属性 - ID

        2.2 线程属性 - 名称

        2.3 线程属性 - 后台线程

        2.4 线程属性 - 判断 PCB 是否存活

        2.5 线程属性 - 终止线程

        3.0 补充细节

        3.1 Thread.sleep() 的异常处理方式

        3.2 变量捕获


        1.0 创建线程对象并命名

语法结构:

//方法一:Thread t = new Thread(String);//方法二:Thread t1 = new Thread(Runnable target String name);

举个例子:

public class demo5 {    public static void main(String[] args) {        Thread thread = new Thread(() -> {            while (true){                System.out.println("正在执行 run");            }        },"自定义名字");        thread.start();        while (true){            System.out.println("正在运行主线程");        }    }}

通过 jconsole 引用程序来查看线程名字:可以发现“自定义名字”这个线程的名称。

        2.0 线程属性

        2.1 线程属性 - ID

        属于线程自己的 ID ,与 PCB 中的属性 PID 不一样,也不是一一对应的。但是线程与 PCB 是一一对应的,编号不是同一个体系。

获取 ID 的方法:

long id = thread.getId();

举个例子:

public class demo5 {    public static void main(String[] args) {        Thread thread = new Thread(() -> {            System.out.println("正在运行 run");        });        thread.start();        long id = thread.getId();        System.out.println(id);        System.out.println("正在运行主线程");    }}

运行结果:

        也可以通过这个例子发现,手动创建线程是比较慢的,main 线程都执行完毕了,自定义的线程有可能都还没创建完毕。

        2.2 线程属性 - 名称

        获取当前线程的名称,默认名称是:Thread - 0, Thread - 1, Thread - 2 ......

获取线程名称:

        String name = thread.getName();

举个例子:

public class demo5 {    public static void main(String[] args) {        Thread thread = new Thread(() -> {            System.out.println("正在运行 run");        });        thread.start();        String name = thread.getName();        System.out.println(name);        System.out.println("正在运行主线程");    }}

运行结果:

        2.3 线程属性 - 后台线程

        前台线程:也称为用户线程,当所有的前台线程都结束时,程序就会退出。

        后台线程:也称为守护线程,当所有前台结束时,后台线程会自动被终止,即使后台线程还在执行。后台线程通常用于执行一些辅助性任务,如 gc 垃圾回收,日志记录等。

总的来说,后台线程主要用于支持前台线程的工作,而前台线程则是执行具体的业务逻辑。

        默认都是前台线程,通过设置 daemon 属性来将线程设置为后台线程。

设置 daemon 属性:

Thread thread = new Thread();thread.setDaemon(true); // 将线程设置为后台线程

举个例子:

public class demo6 {    public static void main(String[] args) throws InterruptedException {        Thread thread = new Thread(() -> {            while (true){                System.out.println("正在运行 run");            }        });        thread.setDaemon(true);//设置为后台线程        thread.start();        // main 是前台线程,因为只有一个前台线程,只要 main 结束了,        // 那么整个线程都结束了。        Thread.sleep(1000);    }}

运行结果:

        即使 run 方法还没有结束,但是 main 已经结束了,所以整个进程都会结束。需要注意的是:由于这里只有一个 main 前台线程,所以 main 结束,就会影响整个进程结束。

判断是否为后台线程:

boolean b = thread.isDaemon();

        如果是后台线程,那么返回 true ;反则 false 。

举个例子:

public class demo6 {    public static void main(String[] args) throws InterruptedException {        Thread thread = new Thread(() -> {            while (true){                System.out.println("正在运行 run");            }        });        thread.setDaemon(true);//设置为后台线程        thread.start();        // main 是前台线程,因为只有一个前台线程,只要 main 结束了,        // 那么整个线程都结束了。        Thread.sleep(1000);        System.out.println(thread.isDaemon());            }}

运行结果:

        2.4 线程属性 - 判断 PCB 是否存活

        Thread 对象的生命周期与 PCB 的生命周期是不一定完全一样的。

判断 PCB 是否存活:

Thread t = new Thread();boolean b = t.isAlive();

        如果 pcb 存活,返回的指是 true ;若反则 false 。

举个例子:

public class demo7 {    public static void main(String[] args) {        Thread t = new Thread(() -> {            System.out.println("正在执行 run");        });        //此时上面的 Thread 对象已经创建完成了        //现在来判断 pcb 是否存活        System.out.println(t.isAlive());    }}

运行结果:

        只要当调用 t.start() 方法后,才会创建线程,那么 pcb 在内核中就创建出来了。

代码如下:

public class demo7 {    public static void main(String[] args) {        Thread t = new Thread(() -> {            System.out.println("正在执行 run");        });        t.start();        //此时上面的 Thread 对象已经创建完成了        //现在来判断 pcb 是否存活        System.out.println(t.isAlive());    }}

运行结果:

        2.5 线程属性 - 终止线程

        在 Java 中,可以通过调用 Thread 类的 interrupt() 方法来终止线程。这会向线程发送一个中断信号,线程可以通过检查 isInterrupted() 方法来响应中断并做出相应的处理,通常是安全地终止线程的执行。

举个例子:

public class demo8 {    public static void main(String[] args) {        Thread t = new Thread(() -> {            // 循环条件是对当前的线程判断是否中断了,            // 设置:如果中断了,循环停止;如果没有中断,循环继续。            // 注意注意,这里条件有 ! 。           while ( !Thread.currentThread().isInterrupted()){               System.out.println("正在运行 run");                                //设置 t 线程休息 9 秒               try {                   Thread.sleep(9000);               } catch (InterruptedException e) {                   e.printStackTrace();               }           }        });                //创建线程        t.start();        //设置 main 线程休息 3 秒,        //需要注意的是,如果这里不设置休息时间,        //会导致上面的循环还没进去就被中断了。        try {            Thread.sleep(3000);        } catch (Exception e) {            throw new RuntimeException(e);        }        //中断 t 线程        t.interrupt();    }}

运行结果:

        注意结果,即使将 t 线程中断了,但是循环还在继续执行。这是为什么了?

        先来描述整个过程:创建完 t 线程后,在 main 线程等待的时候,t 开始执行 run 方法中的内容,开始的时候,t 线程是没有中断的,可以顺利进入循环。直到 main 线程等待结束之后,将 t 线程中断了,那么即使 t 线程是否处在 sleep() 等待,都会被立即唤醒,不在等待。因此 t.interrupt(); 这段代码可以理解为做了两个动作,第一个动作将 Thread.currentThread().isInterrupted() 的布尔值改变为 true ;第二个动作立即唤醒 sleep() ,不在等待。(如果代码中没有 sleep() 方法对话,该动作就不出现,只有第一个动作)。

        接着,sleep() 被唤醒的同时,1)会自动清除 Thread.currentThread().isInterrupted() 的布尔值改变为 false ,从而导致了代码中的循环继续运行。这就是原因的关键,解释了即使将 t 线程中断了,但是循环还在执行的理由。之所以要改回来,就是把控制权转交给程序员自己。2)sleep() 被唤醒同时会执行 catch() 方法中的代码。

        所以程序员就可以在 catch() 方法中设置自己的思路,假如要中断 t 线程的话,只需要在 catch() 中直接写 break; 即可,就会中断循环了。t 线程也就是结束了。

代码如下:

public class demo8 {    public static void main(String[] args) {        Thread t = new Thread(() -> {           while ( !Thread.currentThread().isInterrupted()){               System.out.println("正在运行 run");               try {                   Thread.sleep(9000);               } catch (InterruptedException e) {                   break;               }           }        });        t.start();        try {            Thread.sleep(3000);        } catch (Exception e) {            throw new RuntimeException(e);        }        t.interrupt();    }}

运行结果:

        3.0 补充细节

        3.1 Thread.sleep() 的异常处理方式

        在 main 方法中处理 sleep 有两种选择:1)throws  2)try catch

public class demo12 {    public static void main(String[] args) throws InterruptedException {        Thread.sleep(1000);    }}
public class demo12 {    public static void main(String[] args) {        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            throw new RuntimeException(e);        }    }}

        在线程的 run 中就只有一个选择了:try catch

public class demo10 {    public static void main(String[] args) {        Thread t = new Thread(() -> {            System.out.println("正在执行 run ");            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                throw new RuntimeException(e);            }        });            }}

        这是因为 throw 也是方法签名的一部分,在 run 方法重写的时候,就要求方法的签名得是一样的。

        method sign ature 包含:1)方法名字 2)方法的参数列表 3)声明抛出的异常

        3.2 变量捕获

         在 Java 中,变量捕获通常指的是在 Lambda 表达式或匿名内部类中引用外部作用域中的局部变量。当 Lambda 表达式或匿名内部类引用外部作用域的局部变量时,这些变量会被隐式地捕获并保存下来,使得在 Lambda 表达式或匿名内部类中可以访问和修改这些变量的值。

        Lambda 表达式和匿名内部类可以捕获外部作用域中的 final 或 effectively final 局部变量(即不可修改的变量)。

        简单来说,在 Lambda 表达式或者在匿名内部类中要引用外部作用域的局部变量的话,要求该局部变量是常量或者从头到尾都没有修改的变量。

        如果在 Lambda 表达式或匿名内部类中尝试修改非 final 或 effectively final 的局部变量,编译器会报错。这种错误通常称为:

"Local variable is accessed from within inner class, needs to be declared final"


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/87634.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 全文蝴蝶梦结局+番外精选作品之一(闵暖季司凉)列表_全文蝴蝶梦结局+番外精选作品之一
  • 相思两别离悬念章节免费释出_「冉冉盛今安宋言心」最新后续章节在线阅读
  • 我给第三十八任老公过喜结局+番外(宋青青傅洛)列表_我给第三十八任老公过喜结局+番外(宋青青傅洛)全书+后续+结局在线
  • 水自无情舟渡人季铭穆婉结局+番外(季铭穆婉)_(水自无情舟渡人季铭穆婉结局+番外)列表_笔趣阁(季铭穆婉)
  • 我给第三十八任老公过喜全列表_我给第三十八任老公过喜全(宋青青聂子远)
  • 完结文玫瑰越过荆棘,苏清苒裴安煜免费+后续列表_完结文玫瑰越过荆棘,苏清苒裴安煜免费+后续
  • 全文他站在回忆尽头番外+结局(乔若兮沈辞安)列表_全文他站在回忆尽头番外+结局
  • (番外)+(全书)(岑时晏叶照绵)_叶照绵与岑时晏的+后续+结局列表_笔趣阁(岑时晏叶照绵)(岑时晏叶照绵)完结_(岑时晏叶照绵)列表_笔趣阁(叶照绵与岑时晏的+后续+结局)
  • [逆来顺受的妈妈]全文免费在线阅读_朋友明白独家章节限时试读
  • (番外)+(全书)我给第三十八任老公过喜+全书+番外_(宋青青聂子远结局+番外)我给第三十八任老公过喜+全书+番外列表_笔趣阁(宋青青聂子远结局+番外)
  • 顾承景江纪棠(血染征袍决朱颜顾承景江纪棠结局+后续全面完结)免费在线_(血染征袍决朱颜顾承景江纪棠结局+后续全面完结)顾承景江纪棠免费精彩片段
  • 父母葬礼日,未婚夫要和女秘书领证结婚情感冲突名场面试读章_「柳如眉明白大少爷」限免完整章节合集‌

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1