初始计算机操作系统 您所在的位置:网站首页 操作系统中并发和并行的概念区别 初始计算机操作系统

初始计算机操作系统

2023-05-26 02:21| 来源: 网络整理| 查看: 265

Thread 的几个基本属性 getId() Id  ID 是线程的唯一标识,不同线程不会重复 getName()名称 getState()状态 getPriority()优先级 isDaemon()是否后台线程

是否是守护线程//

前台进程会阻止进程结束,前台进程工作没完,进程是完不了的; 后台进程不会阻止进程的结束,后台线程工作没完,进程也是可以结束的; 代码中手动创建的线程,默认都是前台的;包括main也是的其他jvm自带的线程都是后台的; 也可以 使用setDeamon设置成后台线程(守护线程)(被设置的这个线程就与t无关了) ,  关于后台线程,需要记住一点: JVM 会在一个进程的所有非后台线程结束后,才会结束运行 是否存活,即简单的理解,为 run 方法是否运行结束了

isAlive() 是否存活 就是判断是否真的有线程, 调用start后,才会在内核创建一个PCB,此时的一个PCB才表示一个真正的线程,此时isAlive()才是true; 另外,如果内核把线程把run干完了,此时线程销毁,pcb随之销毁,但是Thread t这个对象不一定释放 此时isAlive()还是false; t神魔时候不在了?当引用不指向这个对象,被GC回收; run方法在执行的时候 isAlive ()->true; 执行完->false isInterrupted() 是否被中断

中断一个线程,不是让线程立刻停止,而是通知线程需要停止了,是否真的停止,取决于具体代码的书写方式;

为true,表示被终止;

为false,表示为被终止;

1.自定义方式

缺点就是不能及时响应,尤其是在sleep休眠的时候比较久的情况

//使用标志 public static boolean flg=true; public static void main(String[] args) throws InterruptedException { Thread t=new Thread(()->{ while(flg){ System.out.println("hello thread"); } try{ Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } }); t.start(); Thread.sleep(3000); flg=false; }

2.使用Thread自带的标志位

这种的是可以唤醒sleep的

使用 Thread.interrupted() 或者 Thread.currentThread().isInterrupted() 代替自定 义标志位. (Thread.currentThread()是Thread的静态方法,通过这个对象可以获取到当前的线程,哪个方法调用线程,得到的就是哪个线程对象的调用) Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记 . 在main中调用t.interrupted(),就相当于main通知t要终止了;

public static void main(String[] args) throws InterruptedException { Thread t=new Thread(()->{ while(!Thread.currentThread().isInterrupted()){ System.out.println("hello thread"); try{ Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); t.start(); Thread.sleep(3000); t.interrupt();//把boolean操作封装到Thread的方法里了 }

如果线程在sleep中休眠 ,此时调用interrupt会把t唤醒 ,从sleep中提前返回 ;

interrupt会做两件事情 ,

1.把线程内部的标志位设置成true;

2.如果线程在进行sleep ,就会触发异常,把sleep唤醒;

但是sleep在唤醒的时候 ,还会把刚才设置的标志位再设置回false(清空标志位);

像wait,join这样的造成代码暂停的方法都会有类似的清除标志位的设定

所以这个时候执行 ,还可能会导致sleep中被interrupted之后 ,还会继续执行,即线程t忽略了终止请求;

在catch里面可以加上break(也可以根据需求添加sleep)/catch里面改成throw new RuntimeException(e);让线程t立即相应你的终止请求

so , 唤醒之后到底让线程立即终止还是稍后 ,就把选择权交给程序员自己了 。

为啥不涉及成A让B终止 ,B就终止呢 ? A,B之间是并发执行的,随即调度的 ,导致B这个线程执行到哪了,A都是不清楚的 。

等待线程(join)

线程是一个随机调度的过程,等待线程就是控制两个线程之间的结束顺序 。

public class demo5 { public static void main(String[] args) throws InterruptedException { Thread t=new Thread(()->{ for (int i = 0; i < 3; i++) { System.out.println("hello thread"); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); t.start(); System.out.println("join之前"); t.join(); //这里的join是让main等待t执行结束;(等待t的run执行完) //本身执行完start之后,t线程和main线程就并发执行,分头执行main继续向下执行,t也继续向下执行就会发生阻塞block //一直阻塞到t线程执行完,main才能从join里面恢复过来 //必然是t先结束 System.out.println("join之后"); } }

——> main线程中的打印“join之前”执行,遇到join,等待t线程执行完后才执行后续的;

 

😅如果执行join的时候 ,t 已经结束了,join 就不会阻塞 ,立即返回 ;

 so,有 join 也不一定必须得等待 ;



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有