初始计算机操作系统 | 您所在的位置:网站首页 › 操作系统中并发和并行的概念区别 › 初始计算机操作系统 |
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要终止了;![]() 如果线程在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 实验室设备网 版权所有 |