㈠ java 怎么强制关闭 一个线程
在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy() and resume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。
在Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中详细讲解了舍弃这些方法的原因。
如果真的需要终止一个线程,可以使用以下几种方法:
1、让线程的run()方法执行完,线程自然结束。(这种方法最好)
2、通过轮询和共享标志位的方法来结束线程,例如while(flag){},flag的初始值设为真,当需要结束时,将flag的值设为false。(这种方法也不很好,因为如果while(flag){}方法阻塞了,则flag会失效)
如果线程因为执行sleep()或是wait()而进入Not Runnable状态,假如是wait() 用标志位就方法就不行了,
public final void wait(long timeout)
throws InterruptedException此方法导致当前线程(称之为 T)将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求。即当前线程变为等待状态
wait() 的标准使用方法
synchronized(obj){
while(<不满足条件>){
obj.wait();
}
满足条件的处理过程
}
而您想要停止它,您可以使用第三种即
3 使用interrupt(),而程式会丢出InterruptedException例外,因而使得执行绪离开run()方法
㈡ 如何关闭java线程
终止线程的三种方法
1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
3. 使用interrupt方法中断线程。
1. 使用退出标志终止线程
当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。下面给出了一个利用退出标志终止线程的例子。
package chapter2;
public class ThreadFlag extends Thread
{
public volatile boolean exit = false;
public void run()
{
while (!exit);
}
public static void main(String[] args) throws Exception
{
ThreadFlag thread = new ThreadFlag();
thread.start();
sleep(5000); // 主线程延迟5秒
thread.exit = true; // 终止线程thread
thread.join();
System.out.println("线程退出!");
}
}
在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false.在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值,
2. 使用stop方法终止线程
使用stop方法可以强行终止正在运行或挂起的线程。我们可以使用如下的代码来终止线程:
thread.stop();
虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。
3. 使用interrupt方法终止线程
使用interrupt方法来终端线程可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){……}来判断线程是否被中断。
在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。
package chapter2;
public class ThreadInterrupt extends Thread
{
public void run()
{
try
{
sleep(50000); // 延迟50秒
}
catch (InterruptedException e)
{
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws Exception
{
Thread thread = new ThreadInterrupt();
thread.start();
System.out.println("在50秒之内按任意键中断线程!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println("线程已经退出!");
}
}
上面代码的运行结果如下:
在50秒之内按任意键中断线程!
sleep interrupted
线程已经退出!
在调用interrupt方法后, sleep方法抛出异常,然后输出错误信息:sleep interrupted.
注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。因此,while (!isInterrupted())也可以换成while (!Thread.interrupted())。
㈢ java中终止线程的方法
在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(),stop(),stop(Throwable)andsuspend(),destroy()andresume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。本文是海文国际小编搜索整理的关于JAVA中终止线程的方法,供参考复习,希望对大家有所帮助!
如果真的需要终止一个线程,可以使用以下几种方法:
1、让线程的run()方法执行完,线程自然结束。(这种方法最好)
2、通过轮询和共享标志位的方法来结束线程,例如while(flag){},flag的初始值设为真,当需要结束时,java课程培训机构建议将flag的值设为false。(这种方法也不很好,因为如果while(flag){}方法阻塞了,则flag会失效)
㈣ 求教高手:java中如何暂停一个线程中的任务,在以后的可以恢复之前任务的执行。
可以用以下几种方法:
interrupt():中断线程
stop():强迫线程停止执行。用 Thread.stop 来终止线程将释放它已经锁定的所有监视器(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。
yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。yield()只能使同优先级的线程有执行的机会。----这句是重点
3.书上说yelid()是礼让,是让当前执行线程停下来给别的线程资源, 又说没有任何机制保证会这样。----------没有任何机制保证执行yield()的线程一定会把资源让给其它线程。打个比方:两个人抢东西,A抢到了B没有,再把东西放回去重抢,说不定还是A抢到B没有。没有任何机制保证放回去后B一定能抢到
sleep方法使线程睡眠,但是到一定毫秒数时会自动到cpu中等待
wait方法使线程等待,但是不会自动到cpu中等待,要通过notify或者notifyall方法进行唤醒。
以上是让线程等待的方法,你可以选择适合你程序的方法。
㈤ Java中如何正确而优雅的终止运行中的线程
Java中终止线程的方式主要有三种:
1、使用stop()方法,已被弃用。原因是:stop()是立即终止,会导致一些数据被到处理一部分就会被终止,而用户并不知道哪些数据被处理,哪些没有被处理,产生了不完整的“残疾”数据,不符合完整性,所以被废弃。So, forget it!
2、使用volatile标志位
看一个简单的例子:
首先,实现一个Runnable接口,在其中定义volatile标志位,在run()方法中使用标志位控制程序运行
{
//定义退出标志,true会一直执行,false会退出循环
//使用volatile目的是保证可见性,一处修改了标志,处处都要去主存读取新的值,而不是使用缓存
publicvolatilebooleanflag=true;
publicvoidrun(){
System.out.println("第"+Thread.currentThread().getName()+"个线程创建");
try{
Thread.sleep(1000L);
}catch(InterruptedExceptione){
e.printStackTrace();
}
//退出标志生效位置
while(flag){
}
System.out.println("第"+Thread.currentThread().getName()+"个线程终止");
}
}
然后,在main()方法中创建线程,在合适的时候,修改标志位,终止运行中的线程。
publicclassTreadTest{
publicstaticvoidmain(String[]arg)throwsInterruptedException{
MyRunnablerunnable=newMyRunnable();
//创建3个线程
for(inti=1;i<=3;i++){
Threadthread=newThread(runnable,i+"");
thread.start();
}
//线程休眠
Thread.sleep(2000L);
System.out.println("——————————————————————————");
//修改退出标志,使线程终止
runnable.flag=false;
}
}
最后,运行结果,如下:
第1个线程创建
第2个线程创建
第3个线程创建
--------------------------
第2个线程终止
第1个线程终止
第3个线程终止
3、使用interrupt()中断的方式,注意使用interrupt()方法中断正在运行中的线程只会修改中断状态位,可以通过isInterrupted()判断。如果使用interrupt()方法中断阻塞中的线程,那么就会抛出InterruptedException异常,可以通过catch捕获异常,然后进行处理后终止线程。有些情况,我们不能判断线程的状态,所以使用interrupt()方法时一定要慎重考虑。
㈥ java线程关闭时会执行结束线程的方法吗
在Java服务正常关闭或重启时,未执行完的线程会被中止。但是,这并不意味着线程会立即终止或丢失。在一个正常关闭或重启的过程中,Java虚拟机会尝试以一种安全的方式停止所有的线程。
正常关闭:
当你调用System.exit()或者通过其他方式(例如:在Spring Boot应用中使用/shutdown端点)正常关闭应用时,Java虚拟机会尝试停止所有的非守护线程。如果线程在合理的时间内没有响应停止请求,那么Java虚拟机会使用更强硬的手段来停止它们。
你可以通过在线程上调用Thread.interrupt()方法来中断线程。这将设置线程的中断状态,如果线程处于阻塞、等待、睡眠或占用状态,那么它将抛出InterruptedException。
如果你的应用有未完成的业务逻辑,通常的做法是确保这些线程在完成当前任务后可以优雅地停止。例如,如果你的线程正在处理数据库操作,你可能希望在线程停止之前确保所有的数据库事务都已完成。
重启:
重启通常涉及到停止当前运行的Java进程并启动一个新的进程。这通常通过你的操作系统或脚本(如systemd、supervisord、upstart等)来完成。
在重启期间,所有未完成的线程将被中止。然而,如果你的应用在重启前可以确保所有的线程都已完成或可以安全地中止,那么这通常不会造成问题。
在处理需要长时间运行的任务或在重启前需要清理资源(如数据库连接)的情况时,要确保你的代码可以优雅地处理这些场景。
未执行完的线程:
如果Java应用在关闭或重启时还有未执行完的线程,Java虚拟机会尝试停止它们。这意味着这些线程将被中止,并且不会完成它们的任务。
这可能会导致未完成的数据处理、数据库事务或其他业务逻辑被丢失。因此,重要的是要确保你的应用可以安全地处理这些线程的停止。
在一些情况下,你可能需要使用持久化机制(如数据库、消息队列等)来确保即使在应用关闭或重启后,数据也不会丢失。
总的来说,Java服务在关闭或重启时会尝试以一种安全的方式停止所有的线程。但是,你仍然需要确保你的代码可以优雅地处理线程的停止,并确保任何未完成的业务逻辑在关闭或重启过程中被正确处理。