- 浏览: 898030 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
小宇宙_WZY:
膜拜一下大神,解决了我一个大问题,非常感谢 orz
【解惑】深入jar包:从jar包中读取资源文件 -
JKL852qaz:
感谢,遇到相同的问题!
【解惑】深入jar包:从jar包中读取资源文件 -
lgh1992314:
为什么java中调用final方法是用invokevirtua ...
【解惑】Java动态绑定机制的内幕 -
鲁曼1991:
说的都有道理,protected只能被同一级包的类所调用
【解惑】真正理解了protected的作用范围 -
鲁曼1991:
...
【总结】String in Java
★ 线程状态
Java虚拟机将线程运行过程分成四种状态 。 (1) New 新生;(2) Runnable 可运行;(3) Blocked 阻塞;(4) Dead 死亡。
值得注意的是: 线程的可运行状态并不代表线程一定在运行(runnable != running ) 。 大家都知道:所有现代桌面和服务器操作系统都使用了抢占式的线程调度策略 。一旦线程开始执行,并不是总是保持持续运行状态的。当系统分给它的时间片(非常小的运行时间单位)用完以后,不管程序有没有执行完,线程被强制放弃CPU,进入就绪状态,直到下次被调度后开始继续执行。也就是说, Runnable可运行状态的线程处于两种可能的情况下:(1)占用CPU运行中,(2)等待调度的就绪状态。 这里要声明一下:处于等待调度的就绪状态线程和处于阻塞的线程是完全不同的。就绪的线程是因为时间片用完而放弃CPU,其随时都有可能再次获得CPU而运行,这一切取决于分时OS的线程调度策略。
在很多操作系统的专业术语中,这种因时间片用完而被剥夺CPU的情况我们叫做线程中断 。注意这和我们下面要将得中断线程是两个完全不同的概念。事实上,我们不可能通过应用程序来控制CPU的线程中断,除非我们能够自由调用OS的内核。
★ 中断线程 —— interrupt()
一个正在运行的线程除了正常的时间片中断之外,能否被其他线程控制?或者说其他线程能否让指定线程放弃CPU或者提前结束运行? 除了线程同步机制之外,还有两种方法:
(1) Thread.stop(), Thread.suspend(), Thread.resume() 和Runtime.runFinalizersOnExit() 这些终止线程运行的方法 。这些方法已经被废弃,使用它们是极端不安全的。
(2) Thread.interrupt() 方法是很好的选择。但是使用的时候我们必须好好理解一下它的用处。
//无法中断正在运行的线程代码 class TestRunnable implements Runnable{ public void run(){ while(true) { System.out.println( "Thread is running..." ); long time = System.currentTimeMillis();//去系统时间的毫秒数 while((System.currentTimeMillis()-time < 1000)) { //程序循环1秒钟,不同于sleep(1000)会阻塞进程。 } } } } public class ThreadDemo{ public static void main(String[] args){ Runnable r=new TestRunnable(); Thread th1=new Thread(r); th1.start(); th1.interrupt(); } } //运行结果:一秒钟打印一次Thread is running...。程序没有终止的任何迹象
上面的代码说明interrupt()并没有中断一个正在运行的线程,或者说让一个running中的线程放弃CPU。那么interrupt到底中断什么。
首先我们看看interrupt究竟在干什么。
当我们调用th1.interrput()的时候,线程th1的中断状态(interrupted status) 会被置位。我们可以通过Thread.currentThread().isInterrupted() 来检查这个布尔型的中断状态。
在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 "。好好体会这句话的含义,看看下面的代码:
//Interrupted的经典使用代码 public void run(){ try{ .... while(!Thread.currentThread().isInterrupted()&& more work to do){ // do more work; } }catch(InterruptedException e){ // thread was interrupted during sleep or wait } finally{ // cleanup, if required } }
很显然,在上面代码中,while循环有一个决定因素就是需要不停的检查自己的中断状态。当外部线程调用该线程的interrupt 时,使得中断状态置位。这是该线程将终止循环,不在执行循环中的do more work了。
这说明: interrupt中断的是线程的某一部分业务逻辑,前提是线程需要检查自己的中断状态(isInterrupted())。
但是当th1被阻塞的时候,比如被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞时。调用它的interrput()方法。可想而知,没有占用CPU运行的线程是不可能给自己的中断状态置位的。这就会产生一个InterruptedException异常。
//中断一个被阻塞的线程代码 class TestRunnable implements Runnable{ public void run(){ try{ Thread.sleep(1000000); //这个线程将被阻塞1000秒 }catch(InterruptedException e){ e.printStackTrace(); //do more work and return. } } } public class TestDemo2{ public static void main(String[] args) { Runnable tr=new TestRunnable(); Thread th1=new Thread(tr); th1.start(); //开始执行分线程 while(true){ th1.interrupt(); //中断这个分线程 } } } /*运行结果: java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at TestRunnable.run(TestDemo2.java:4) at java.lang.Thread.run(Unknown Source)*/
评论
<div class="quote_title">Heart.X.Raid 写道</div>
<div class="quote_div">
<p><span style="font-size: small;"> finally子句是不得不执行的。也正是由于它的这个特点,我们常常在程序异常跳出之前执行一些回收资源的动作。用Java编写的数据库程序就是很好的例子,我们总是要在程序中断前关闭所有与数据库的连接的。</span> </p>
<p><span style="font-size: small;"> finally子句的作用不容忽视,有了finally,是不是我们可以在程序结束前执行任何我们想执行的语句呢?也并非这样,有两类语句写在finally块中是需要好好斟酌的。</span> </p>
<p><span style="font-size: small;"> (1) return 语句</span> <span style="font-size: small;">public int f(int n){ try{ int r=n*n; return r; } finally{ if(n==2) return 0; //危险 } }
<pre></pre>
<p> 其中try中的return r;是没有任何作用的,因为在调用的方法返回之前必须执行方法中的finally子句。这样执行到return 0;其实该方法就结束了。比如我们调用f(2),结果返回的一定是0,这样原始值4就被忽略了。这种代码的清晰度是很差的。</p>
<p> (2) 抛出异常语句</p>
InputStream in=....; try{ x(); //有可能抛出了非IOException } catch(IOException e){ e.printStackTrace(); } finally{ in.close(); //如果这里抛出了一个异常,就危险了 }
<pre></pre>
<p> 假设try块中的方法x()抛出了一个FileNotFoundException,而catch块捕捉的却是IOException异常。也就是说这个时候程序应该终止,并抛出FileNotFoundException,但是别忘了还有一个finally块必须先执行,好了,这个时候意外发生了,in.close()也出现异常了,并且抛出了一个IOException,没办法,开始的那个FileNotFoundException会丢失,结果只会抛出IOException而终止程序。</p>
<p> </p>
<p> 这两个问题怎么解决呢?其实也好办,就是尽量不要在finally块中写这两种语句,除非你明确不会出问题。</p>
<span style="font-size: small;">
<p> </p>
</span></span></p>
<p> </p>
</div>
<p> </p>
发表评论
-
NIO
2010-08-05 10:36 0在JDK1.4以前,I/O输入输出处理,我们把它称为旧 ... -
【总结】Java线程同步机制深刻阐述
2010-05-16 10:21 6005全文转载:http://www.iteye ... -
【JDK优化】java.util.Arrays的排序研究
2010-05-12 21:06 9193作者题记:JDK中有很多算法具有优化的闪光点,值得好好研究。 ... -
【JDK优化】 Integer 自动打包机制的优化
2010-03-12 19:14 4203我们首先来看一段代码: Integer i=100; In ... -
【总结】Java与字符编码问题详谈
2009-12-30 09:11 9428一、字符集和字符编码方式 计算机只懂得0/1两种信号 ... -
【解惑】 正确理解线程等待和释放(wait/notify)
2009-12-29 13:40 19771对于初学者来说,下面这个例子是一个非常常见的错误。 /** ... -
【解惑】JVM如何理解Java泛型类
2009-12-16 11:08 12379//泛型代码 public class Pair<T& ... -
【解惑】正确的理解this 和 super
2009-12-05 09:46 4474转载: 《无聊 ... -
【解惑】真正理解了protected的作用范围
2009-11-21 18:00 5095一提到访问控 ... -
【总结】String in Java
2009-11-21 17:52 10986作者:每次上网冲杯Java时,都能看到关于String无休无止 ... -
【解惑】真正理解了protected的作用范围
2009-11-16 17:11 585一提到访问控制符protected,即使是初学者 ... -
总结Java标准类库中类型相互转化的方法
2009-11-09 21:57 210组一: ☆ String → byte[ ... -
方法没覆盖住带来的烦恼
2009-11-05 09:18 100Object类是所有类的祖宗,它的equals方法比较的 ... -
【解惑】数组向上转型的陷阱
2009-11-03 11:44 1890问题提出: 有两个类Manager和Em ... -
【总结】java命令解析以及编译器,虚拟机如何定位类
2009-11-01 16:25 5824学Java有些日子了,一直都使用IDE来写程序。这 ... -
【解惑】剖析float型的内存存储和精度丢失问题
2009-10-26 15:10 16087问题提出:12.0f-11.9f=0.10 ... -
【解惑】领略内部类的“内部”
2009-10-19 15:38 3599内部类有两种情况: (1) 在类中定义一个类(私有内部类 ... -
【解惑】深入jar包:从jar包中读取资源文件
2009-10-08 21:13 65950我们常常在代码中读取一些资源文件(比如图片,音乐,文 ... -
【解惑】理解java枚举类型
2009-09-26 09:37 3427枚举类型是JDK5.0的新特征。Sun引进了一个全新的关键字e ... -
编写自己的equals方法
2009-09-20 14:18 129在我的《令人头疼的"相等"关 ...
相关推荐
在Java编程中,中断线程是一项重要的任务,它允许程序在必要的时候停止或者结束一个正在运行的线程。本教程的压缩包包含了中断线程的源代码实例和详细指导,旨在帮助开发者深入理解和掌握这一核心概念。以下是关于...
在Java编程中,中断线程是一项重要的任务,特别是在多线程环境下,我们可能需要停止某个线程的执行,以优化程序资源的使用或响应特定的系统需求。本示例将详细探讨Java中断线程的正确方法,以确保线程安全且高效地...
要中断线程,需要在 run 方法中检查中断状态标志,并根据需要退出或中断线程。 isInterrupted 方法 isInterrupted 方法用于检查线程的中断状态标志。该方法返回当前线程的中断状态标志。如果该线程的中断状态标志...
当外部请求中断线程时,内部的`isInterrupted()`检查会发现中断状态,从而使循环结束。这种方式允许线程在完成当前任务或清理工作后优雅地退出,而不是立即停止执行。 总结来说,Java多线程的中断机制通过`...
`Thread.interrupt()`方法是中断线程的主要手段,但它的行为并不像字面意义上那样直接终止线程。相反,它通过设置线程的中断状态来向线程发送一个中断信号,这个信号是一个内部标志,告知线程应该停止其当前的工作。...
中断线程的处理是确保应用响应性和用户体验的关键。本篇将详细讲解如何在Android中正确地中断线程,以及处理中断后的工作。 首先,Android中的线程中断主要是通过`Thread.interrupted()`或`Thread.currentThread()....
Java多线程笔记是 Java 编程语言中关于多线程编程的笔记,涵盖了线程基础知识、线程优先级、线程状态、守护线程、构造线程、线程中断等多方面的内容。 获取简单 main 程序中的线程 在 Java 中,可以使用 ...
在Java中,中断线程主要是通过调用`Thread`对象的`interrupt()`方法来实现的。这个方法并不会立即停止目标线程,而是设置一个中断标志,表明线程已被请求中断。如果线程处于阻塞状态(例如在`sleep()`, `wait()`, ...
Java中,`join`方法有类似功能,而`interrupt`方法可以用来中断线程,通常配合`isInterrupted`或`interrupted`检查中断状态。 在实际应用中,线程调度还需要考虑线程同步和互斥问题,以防止数据竞争和死锁。C语言中...
从源码可以看到,`interrupted()`方法实际上调用的是当前线程的`isInterrupted(true)`方法,该方法用于测试当前线程的中断状态。 3. `isInterrupted()`方法 `isInterrupted()`方法是用来测试当前线程是否已经中断...
9. **线程中断**:`interrupt()`方法可以标记线程中断状态,线程可以通过检查`isInterrupted()`或`interrupted()`方法来响应中断请求,从而优雅地停止线程执行。 10. **线程局部变量(ThreadLocal)**:为每个线程...
在Java多线程编程中,理解`Thread`类中的`interrupt()`、`interrupted()`和`isInterrupted()`方法至关重要,因为它们与线程中断机制紧密相关。线程中断是Java提供的一种协作式中断机制,它并不强制结束线程,而是...
- `interrupt()`方法用于请求中断线程。但是,这并不立即停止线程的执行,而是改变线程的中断状态。 - `interrupted()`和`isInterrupted()`方法用于检查线程是否已被中断。`interrupted()`方法会清除中断状态,而`...
- interrupt():中断线程,被中断的线程会抛出InterruptedException。 - isInterrupted() 和 interrupted():检查线程是否被中断。 三、线程同步 为了解决多线程并发访问共享资源可能导致的问题,Java提供了多种...
7. **线程中断**:`interrupt()`方法用于中断线程,中断标志会被设置。线程内部可以通过检查`isInterrupted()`或`interrupted()`来响应中断请求,通常用于终止阻塞操作如`sleep()`或`wait()`。 8. **线程生命周期**...
- `Thread.interrupt()`:标记线程中断状态,通常配合`isInterrupted()`或`interrupted()`检查中断状态,并在适当位置结束线程。 - `InterruptedException`:当线程在阻塞状态下被中断时抛出,需妥善处理。 8. **...
Java 提供了多种方式来中断线程,包括使用 stop() 方法、interrupt() 方法和使用 volatile 变量等。 一、Java 中断线程的方式 Java 中有三种方式来中断线程: 1. 使用 stop() 方法:该方法已经被废弃,因为它可能...
- `interrupt()`方法用于中断线程,但这并不意味着线程会立即停止,而是设置中断标志,线程需在适当位置检查`isInterrupted()`或`interrupted()`方法来响应中断。 - 守护线程(Daemon Thread)是一种后台线程,当...
因此,中断线程后,若需要重新启动,必须创建一个新的`Thread`实例: ```java public void restartThread() { mThread = new MyThread(); mThread.start(); } ``` 在Android开发中,通常推荐使用`Handler`、`...