java并发-Thread类基本方法介绍
来源:互联网 发布:淘宝网退货运费怎么算 编辑:程序博客网 时间:2024/06/07 12:40
待更新
- java.lang.SecurityManager;
Thread中基本方法
1.void suspend()方法
这是一个过时的方法,与void resume()搭配使用来暂停和唤醒一个线程。这两个方法有可能造成独占和不同步的问题—详见《java多线程编程核心技术》。方法源码如下:
@Deprecated public final void suspend() { checkAccess(); suspend0(); }
首先当前线程的checkAccess()方法被调用,其有可能导致SecurityException。如果当前线程时活跃着的,则挂起,调用resume()方法激活。相关方法checkAccess()和suspend0()源码如下:
/** *检测当前运行的线程是否有权限修改这个线程 * 比如main线程使用代码someThread.suspend()来修改someThread线程; *如果有 安全管理器/SecurityManagy,则将被修改的线程作为参数调用安全管理器的 *checkAccess方法。 * *如果当前线程没有权限修改被修改的线程,则抛出SecurityException异常。 */ public final void checkAccess() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkAccess(this); } }
native指Java调用本地方法,通常为非java语言实现
private native void suspend0();//原来源码名称后缀数字的是这个意思
resume()方法同理,也是一个过时的唤醒线程的方法。如果当前线程没有权限修改被唤醒的线程,则抛出SecurityException异常
@Deprecated public final void resume() { checkAccess(); resume0(); }
2.void yield()让当前线程暂时放弃cpu资源
注意:线程放弃cup资源的时间是未知的,可能时间很长,也可能XX。这个方法是可以被scheduler忽略的。yield()是一个用来提高线程之间协作、避免线程过度使用cpu的启发性的尝试,应该小心使用。
实际上,这个方法很少有机会使用,我们在debug或者测试的时候,yield()可能有助于我们处理由于“竞态条件(race conditions)”引起的bug,也有助与我们设计“并发控制结果concurrency control constructs”,比如java.util.concurrent.locks包中的AbstractQueued(Long)Synchronizer使用了这个方法。yield为native方法,源码如下
public static native void yield();
3.线程优先级
线程优先级为1~10,数字越高代表级别越高优先级越高。Thread类中设置了三个默认的优先级属性:
/** * The minimum priority that a thread can have. */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10;
当我们在使用void setPriority(int newPriority) 设置线程的优先级时,数字必须在这个区间。方法源码如下:
/** *final方法:不能被改写;final类不能被继承; * * * */ public final void setPriority(int newPriority) { ThreadGroup g; checkAccess();//检查当前线程是否有修改此线程优先级的权限; if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {//优先级必须在[1,10]之间,否则抛异常:非法参数 throw new IllegalArgumentException(); } //fixme 返回被修改线程所在的线程组,如果被修改线程结束则返回null。如果要设置的值大于所在组线程的可以有的最大值,则自动降低为当前线程组已有的最大值。 if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } setPriority0(priority = newPriority); } }
这里有一个需要注意的点:如果要设置的值大于所在组线程的可以有的最大值,则自动降低为当前线程组已有的最大值。除此之外:
1.线程具有继承性,即被创建的线程与其创建者具有相同的优先级;
2.线程优先级即具有“规则性”,又具有“随机性”,即优先级高的线程有限执行,但其run()方法中任务又不一定是最先执行完。cup只是尽量将资源让给优先级比较高的线程,但是代码先运行、优先级高的线程不一定最先执行完。
综上,线程的优先级具有1.组自贬性;2.继承性;3.随机性
4.守护进程:setDaemon(boolean )
守护进程也可理解为“保姆进程”,当所需要服务的“雇主进程们”结束了,保姆进程自动销毁。最典型的守护进程是GC垃圾回收器。调用Thread 的setDaemon(boolean )方法传参true将进程设置为守护进程,此方法只能在start()调用之间调用,即进程为非存活的状态下。方法源码如下:
public final void setDaemon(boolean on) { checkAccess(); if (isAlive()) {//如果当前线程已经通过start()方法激活,则不能在更改其类型。 throw new IllegalThreadStateException(); } daemon = on;//daemon是Thread类变量,标识其是否是守护进程 }
[补充]:IDEA中变量上右键“Analyze”的子菜单下“Analyze Data Flow to/from Here”可以查看变量的引用情况。
五.停止线程
强迫停止一个线程可以用Thread类的stop()方法,但是这个方法是不安全的,以被标记为deprecated。大多数情况下,停止一个线程使用interrupt()方法。
除非线程要中断本身,否则操作总是被允许的。而且此操作只是为当前线程做标识“可以停止”,而非真正的停止线程。
如果线程在调用wait()、join()、sleep()—等会,加入我们,睡觉及其各种变参多态函数后,再调用interrupt()方法会清空其interurpted的状态,并抛出InterruptedException异常。线程是否是“可停止状态”可以调用两个方法:
1.boolean interrupted():会清除“可停止状态”,测试的是当前线程;
2.boolean isInterrupted():不会清除状态,测试的是Thread对象;
看看源码我们即可知道这两个方法都调用了方法:
//参数表示返回其当前状态后是否将其重新设置为“不可停止”private native boolean isInterrupted(boolean ClearInterrupted);
两个方法源码如下:
public static boolean interrupted() { return currentThread().isInterrupted(true); } public boolean isInterrupted() { return isInterrupted(false); }
停止线程书中讲解了三种方式:
- 异常法;
- 在沉睡中停止;
- 在这里不做讲解的stop()暴力停止;
异常法即当我们使用interrupted()(当前current线程)已经标记为“可停止”时,可以在run()方法中抛出异常并在run()方法的最后捕获异常,以此来停止线程。示例代码如下:
public DemoClass extends Thread{ @Override public void run(){ try{ //doSomeThing if(this.interrupted()){ throw new InterruptedException(); } }catch(InterruptedException e){ //doSomeThing } }}
正如我们上边讲的,如果线程调用wait()、join()、sleep()后再调用interrupt()方法,会清空停止状态并抛异常InterreptedException。使用这个方法也可以停止线程,其实与第一个差不多,我觉得。
六.获取线程id:long getId();
七.让线程休眠指定时间
调用sleep(long million)或者sleep(long millis,int nans)可以使调用方法的线程休眠指定时间,方法可能抛出InterruptedException和IllegalArgumentException,源码如下:
//使当前线程休眠指定毫秒:1秒=1000毫秒 public static native void sleep(long millis) throws InterruptedException;/** *使线程休眠指定毫秒+纳秒,其实精确不了纳秒的级别: * 1.如果纳秒参数>500,000则休眠时间增加1毫秒(相当于向上取整); * 2.如果毫秒参数为0而且纳秒参数不为0,则休眠1毫秒; * 3.纳秒级别的参数不能超过1毫秒,即999,999; * 1ms=1000,000ns(纳秒) * **/ public static void sleep(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) {//纳秒级别的参数不能超过1毫秒 throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos >= 500000 || (nanos != 0 && millis == 0)) { millis++; } sleep(millis); }
八.检测线程是否“存活”
方法源码如下,如果当前线程正在运行或者准备运行都会返回true:
public final native boolean isAlive();
九.返回当前正执行线程的引用
public static native Thread currentThread();
- java并发-Thread类基本方法介绍
- java中Thread类方法介绍
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Spring MVC后台表单校验
- 谷歌商店插件下载crx文件
- Paper: word2vec doc2vec paragraph2vec topic2vec prodct2vec 系列
- g2o卸载命令(适用卸载其他程序)
- 矩阵的压缩存储--特殊矩阵--带状矩阵
- java并发-Thread类基本方法介绍
- maven项目中报找不到${spring.version}jar
- 文件上传下载
- Spring MVC 通过切面,实现超灵活的注解式数据校验
- 启明星第七周学习总结
- js怎么修改系统状态栏
- centos7 命令记录
- 数据挖掘之Apriori算法
- 《西瓜书笔记》(1)机器学习概述(参考答案)