java多线程状态及interrupt()方法
2016-07-01 16:56
483 查看
在java多线程中,线程的状态有 NEW, Runnable, Blocked, Waiting, Timed_Waiting, Terminated. 这是java虚拟机下的线程状态,与操作系统下的线程状态略有不同。线程状态以枚举类型定义在Thread.State中,并且当前线程可以通过getState()方法获取当前线程的状态。Runnable其实可以有两种状态,一种是获得了cpu,这在运行,这里把它表示为Running,另一种在队列中,等待调度。
这些状态之间的转化关系可以通过下面的转化图表示:
有些过程没有写,不然太乱了。
这里重点说一下stop()以及interrupt。
对于stop()方法,直接终止线程,释放线程所获的资源,但是在释放过程中会造成对象状态不一致,从而使程序进入未知的境地,已经很久不推荐使用了。可以通过设定标志位来检测线程终止状态,使线程自动终止。简略实现如下:
boolean stop = false;
public void run(){
while(!stop){
}
}
在需要终止线程的地方把stop设置为true即可。
interrupt方法好多初学者会感到困惑,发现一些情况下并不能终止线程。在java API中有对此详细的说明:
如果线程在调用
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个
因此,可以看出,interrupt之后作用到wait() join() 已经sleep()上。 2014阿里巴巴笔试题的附加题中对这个知识进行了终点考核,其代码如下:
[java] view
plain copy
public class TestInterrupt {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread thread1 = new Thread(){
public void run(){
try{
long time = System.currentTimeMillis();
while(System.currentTimeMillis()-time<2000){
}
System.out.println("A1");
}
catch(Exception e)
{
System.out.println("B1");
}
}
};
thread1.start();
thread1.interrupt();
//在线程sleep状态下进行中断
Thread thread2 = new Thread(){
public void run(){
try {
this.sleep(2000);
System.out.println("A2");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("B2");
}
}
};
thread2.start();
thread2.interrupt();
//在线程wait状态下进行中断,其中wait()没有在同步块中
Thread thread3 = new Thread(){
public void run(){
try {
this.wait(2000);
System.out.println("A3");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("B3");
}
}
};
thread3.start();
thread3.interrupt();
//在线程wait状态下进行中断,其中wait()在同步块中
Thread thread4 = new Thread(){
public void run(){
try {
synchronized(this){
this.wait(2000);
System.out.println("A4");}
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("B4");
}
}
};
thread4.start();
thread4.interrupt();
try{
thread4.start();
System.out.println("A5");
}
catch(Exception e)
{
System.out.println("B5");
System.out.println(e.toString());
}
}
}
我们可以运行,发下运行结果如下(不考虑执行顺序):
A1
B2
B3
B4
B5
这些状态之间的转化关系可以通过下面的转化图表示:
有些过程没有写,不然太乱了。
这里重点说一下stop()以及interrupt。
对于stop()方法,直接终止线程,释放线程所获的资源,但是在释放过程中会造成对象状态不一致,从而使程序进入未知的境地,已经很久不推荐使用了。可以通过设定标志位来检测线程终止状态,使线程自动终止。简略实现如下:
boolean stop = false;
public void run(){
while(!stop){
}
}
在需要终止线程的地方把stop设置为true即可。
interrupt方法好多初学者会感到困惑,发现一些情况下并不能终止线程。在java API中有对此详细的说明:
如果线程在调用
Object类的
wait()、
wait(long)或
wait(long, int)方法,或者该类的
join()、
join(long)、
join(long, int)、
sleep(long)或
sleep(long, int)方法过程中受阻,则其中断状态将被清除,它还将收到一个
InterruptedException。
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个
ClosedByInterruptException。
因此,可以看出,interrupt之后作用到wait() join() 已经sleep()上。 2014阿里巴巴笔试题的附加题中对这个知识进行了终点考核,其代码如下:
[java] view
plain copy
public class TestInterrupt {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread thread1 = new Thread(){
public void run(){
try{
long time = System.currentTimeMillis();
while(System.currentTimeMillis()-time<2000){
}
System.out.println("A1");
}
catch(Exception e)
{
System.out.println("B1");
}
}
};
thread1.start();
thread1.interrupt();
//在线程sleep状态下进行中断
Thread thread2 = new Thread(){
public void run(){
try {
this.sleep(2000);
System.out.println("A2");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("B2");
}
}
};
thread2.start();
thread2.interrupt();
//在线程wait状态下进行中断,其中wait()没有在同步块中
Thread thread3 = new Thread(){
public void run(){
try {
this.wait(2000);
System.out.println("A3");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("B3");
}
}
};
thread3.start();
thread3.interrupt();
//在线程wait状态下进行中断,其中wait()在同步块中
Thread thread4 = new Thread(){
public void run(){
try {
synchronized(this){
this.wait(2000);
System.out.println("A4");}
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("B4");
}
}
};
thread4.start();
thread4.interrupt();
try{
thread4.start();
System.out.println("A5");
}
catch(Exception e)
{
System.out.println("B5");
System.out.println(e.toString());
}
}
}
我们可以运行,发下运行结果如下(不考虑执行顺序):
A1
B2
B3
B4
B5
相关文章推荐
- Java中的匿名内部类总结
- java虚拟机之内存区域与内存溢出异常
- java Collections 排序--多条件排序
- eclipse 异常 Subversion Native Library Not Available解决方案
- Java基础——数据类型之间的转换
- java 知识结构
- spring boot/cloud 应用监控
- Java5新特征之foreach语句使用总结
- Java Executor 框架
- MD5加密算法的java实现
- JAVA调用BAPI创建销售订单
- Java中Synchronized的用法
- Spring之LoadTimeWeaver——一个需求引发的思考---转
- Graphics2D 绘制图形
- [leetcode-371]Sum of Two Integers(java)
- Graphics类提供基本的几何图形绘制方法,主要有:画线段、画矩形、画圆、画带颜色的图形、画椭圆、画圆弧、画多边形等。
- spring 源码分析之BeanPostProcessor
- 使用Eclipse构建Maven的SpringMVC项目
- Weka-无监督属性过滤器-Interquartile[6-3]
- java实现模拟登录itunes后台收入,抓取收入数据,校对收入