当前位置: > 财经>正文

Java终止线程有哪几种方式?那终止进程呢? 外汇交易保险模式有哪几种方式呢图片大全图解

2023-07-26 13:11:58 互联网 未知 财经

Java终止线程有哪几种方式?那终止进程呢?

在讨论线程终止的方式前,我们先讨论一个问题,线程和进程有什么区别?

简而言之,进程是程序运行和资源分配的基本单位,而线程是CPU调度的基本单元,一个程序至少有一个进程,一个进程至少包含一个线程(一个进程可以包含多个线程),简单来说,线程是进程当中的一条执行流程。所以,同一个进程内,多个线程之间可以共享数据和资源,减少切换次数(并发),从而效率更高,但是由于每个线程都有一套独立的寄存器和栈,所以线程的控制流是相对独立的。

如何理解上面这句减少切换次数?举个例子,你要做一道菜:做一个番茄鸡蛋葱花汤,那么,是不是可以在热汤的过程中,打鸡蛋进行搅拌呢?这个过程中,你还可以做点其他的东西?谁会傻傻的等在锅边?什么?你不知道这道菜的流程?

好吧,我先说下如何做这道菜吧,烧热水,烫一下洗净的番茄,对番茄进行剥皮,然后切成细块,锅里烧油,油温八成热,倒入番茄,加盐炒(不加盐番茄炒不成汁),待番茄炒成番茄汁,加入凉水,大伙烧,然后碗中打入几个蛋,放入一点点盐,一点点白醋,搅拌均匀,待锅中水热,取一双筷子,碗口对准筷子,筷子立于锅中,将鸡蛋均匀倒入锅中,1至2分钟以后,撒入洗净切好的葱花即可。

第一次烧热水的时候,你会傻傻的等着吗?肯定不会吧,这个时候可以洗好葱花,洗好番茄,并将葱花切好,如果可以的话,你甚至可以将蛋也打了。这样的话,第二次烧热水的时候,你甚至可以刷刷技术博客,做个好学的孩子。这个就是CPU管理多个进程的初步想法:交替执行。并且,CPU可以在进程间切换,比如你在做菜的时候,突然想喝杯红酒,你就可以在空隙时间喝哟。

那么,如何理解进程和线程的关系呢? 1)一个进程中可以同时存在多个线程; 2)并且各个线程之间可以并发执行; 3)各个线程之间可以共享数据和资源等; 4)一个进程中的一个线程挂了,会导致该进程中的所有线程都挂了。

比如做番茄鸡蛋葱花汤的时候,一旦番茄搞没了,或者鸡蛋不小心把蛋壳丢碗里,鸡蛋丢垃圾桶里,其他线程就气死了,这个番茄鸡蛋葱花汤就凉凉了。

线程有哪些状态? 线程通常都有五种状态,新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)。 1、新建状态:当程序使用new关键字创建了一个线程对象后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量的值,在未调用该对象的start方法之前,线程都处于新建状态。

2、就绪状态:当线程对象调用了start()方法之后,该线程就进入了就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行。但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。

3、运行状态:如果处于就绪状态的线程获得了 CPU,开始执行 run()方法的线程执行体,则该线程处于运行状态;也就是线程调度程序将处于就绪状态的线程设置为当前线程,开始运行run函数当中的代码。

4、阻塞状态:线程正在运行的时候,被暂停,通常可以理解为指线程因为某种原因放弃了cpu使用权,sleep,suspend,wait等方法都可以导致线程阻塞。阻塞的情况分3种,分别是等待阻塞、同步阻塞和其他阻塞。

5、死亡状态:如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

Java中终止线程有哪几种方式?

1、正常运行结束:如果面试问到这个问题,一般人都会想不到有一种方式可以正常终止线程,那就是正常运行结束。

2、使用退出标志退出线程:使用退出标识,使得线程正常退出,即当run方法完成后进程终止。

/** * 使用退出标志结束线程 */public class UseOutSignEndThreadTest extends Thread { public static boolean exit = true; // 重写run方法,run方法的方法体就是现场执行体public void run() {while (!exit) {System.out.println("线程终止!");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("结束!");break;}} public static void main(String[] args) {exit = false;new UseOutSignEndThreadTest().start();} }

3、使用interrupt方法中断线程

需要注意的是:interrupt()方法不像stop方法强行终止一个线程,它只是把要被停止的线程设置成中断状态,而此时要被中断的线程是可以继续执行的。

/** * 使用interrupt()结束线程 */public class UseInterruptEndThreadTest extends Thread {@Overridepublic void run() {super.run();for (int i = 0; i < 4; i++) {if (this.isInterrupted()) {System.out.println("线程已经结束!");break;}System.out.println("i=" + (i + 1));}System.out.println("我要证明线程未真正结束!");}public static void main(String[] args) {try {UseInterruptEndThreadTest thTest = new UseInterruptEndThreadTest();thTest.start();Thread.sleep(20);thTest.interrupt();} catch (InterruptedException e) {e.printStackTrace();}}}程序执行结果:i=1i=2i=3i=4我要证明线程未真正结束!

所以,使用interrupt()方法来中断线程需要考虑两种情况:

1)线程处于阻塞状态:如使用了sleep,同步锁的wait,socket中的receiver,accept等方法时,会使线程处于阻塞状态。当调用线程的interrupt()方法时,会抛出InterruptException异常。阻塞中的那个方法抛出这个异常,通过代码捕获该异常,然后break跳出循环状态,从而让我们有机会结束这个线程的执行。这种方法也叫做抛异常法。

/** * 使用interrupt()结束线程 但是线程处于阻塞状态 */public class UseInterruptEndThreadAndThreadInBlockedTest extends Thread {@Overridepublic void run() {super.run();try {for (int i = 0; i < 1000; i++) {if (this.isInterrupted()) {System.out.println("线程已经结束!");// 改动break为抛出异常(抛异常法)throw new InterruptedException();}System.out.println("i=" + (i + 1));}System.out.println("我想证明抛异常的时候线程已经结束了,可惜没办法输出!");} catch (InterruptedException e) {System.out.println("捕获InterruptedException异常");e.printStackTrace();}System.out.println("我要证明我是否还活着");}public static void main(String[] args) {try {UseInterruptEndThreadAndThreadInBlockedTest thTest = new UseInterruptEndThreadAndThreadInBlockedTest();thTest.start();Thread.sleep(20);thTest.interrupt();} catch (InterruptedException e) {e.printStackTrace();}}}

循环中设置的数值越大,效果越明显。通常很多人认为只要调用interrupt方法线程就会结束,实际上是错的,一定要先捕获InterruptedException 异常之后通过break来跳出循环,才能正常结束run方法。

2)线程未处于阻塞状态:使用isInterrupted()判断线程的中断标志来退出循环。当使用interrupt()方法时,中断标志就会置true,和使用自定义的标志来控制循环是一样的道理。

isInterrupted()和interrupted()方法有什么区别?

isInterrupted()判断的是调用它的对象所启动的线程是否处于中断状态,而不是判断当前线程。

interrupted()方法是静态方法,它判断的是当前线程是否中断

/** * 使用isInterrupt() */public class UseIsInterruptEndThreadTest extends Thread {@Overridepublic void run() {super.run();try {for (int i = 0; i < 1000; i++) {if (this.isInterrupted()) {System.out.println("线程已经结束!");// 改动break为抛出异常(抛异常法)throw new InterruptedException();}System.out.println("i=" + (i + 1));} System.out.println("我想证明抛异常的时候线程已经结束了,可惜没办法输出!");} catch (InterruptedException e) {System.out.println("捕获InterruptedException异常");e.printStackTrace();}System.out.println("我要证明我是否还活着"); } public static void main(String[] args) {try {UseIsInterruptEndThreadTest thTest = new UseIsInterruptEndThreadTest();thTest.start();Thread.sleep(20);thTest.interrupt();//System.out.println("1interrupted thread is stop=" + thTest.interrupted()); //false//System.out.println("2interrupted thread is stop=" + thTest.interrupted()); //falseSystem.out.println("1isInterrupted thread is stop=" + thTest.isInterrupted()); //trueSystem.out.println("2isInterrupted thread is stop=" + thTest.isInterrupted()); //true} catch (InterruptedException e) {e.printStackTrace();}}}

那么,如何终止进程呢?

1)正常结束。进程正常执行结束,不就终止了么? 2)异常结束。机器崩了,进程跑不动,也就死了。 3)外界干预。进程正欢呼雀语呢,一个kill,死了。  

版权声明: 本站仅提供信息存储空间服务,旨在传递更多信息,不拥有所有权,不承担相关法律责任,不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请发送邮件至 举报,一经查实,本站将立刻删除。