当前位置:首页 > 编程教程 > java技术文章 > Java终止线程实例和stop()方法源码阅读

实例分析Java终止线程和stop()方法

  • 发布时间:
  • 作者:码农之家
  • 点击:167

这篇文章主要知识点是关于Java、终止线程、stop()、的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

你不知道的JavaScript(上卷)
  • 类型:JS大小:8.4 MB格式:PDF作者:普森
立即下载

Java终止线程实例和stop()方法源码阅读

了解线程

概念

线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。

线程特点

拥有状态,表示线程的状态,同一时刻中,JVM中的某个线程只有一种状态;

·NEW

尚未启动的线程(程序运行开始至今一次未启动的线程)

·RUNNABLE

可运行的线程,正在JVM中运行,但它可能在等待其他资源,如CPU。

·BLOCKED

阻塞的线程,等待某个锁允许它继续运行

·WAITING

无限等待(再次运行依赖于让它进入该状态的线程执行某个特定操作)

·TIMED_WAITING

定时等待(再次运行依赖于让它进入该状态的线程在指定等待时间内某个特定操作)

·TERMINATED

已退出的线程

拥有优先级,决定线程的执行顺序;

1至10之间的整数,默认数值为5。数值越高,执行的几率越高,优先级并不能决定线程的执行顺序。

子线程的优先级默认同父线程的一样。

注意,当以下情况发生时,JVM将停止执行所有线程:

Runtime(运行时)的exit ()方法被调用并且该方法的调用被Security Manager所允许;

所有的“非守护线程”都已停止运行(无论时正常停止还是一场停止);

可以被标记为守护程序(Daemon)

守护线程的子线程仍是守护线程;

守护线程也就是“后台线程”,一般用来执行后台任务,而用户线程一般用户执行用户级任务。

终止线程的方法

1.使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。下面给出了一个利用退出标志终止线程的例子。

FlagExitThread.java

package com.rainmonth;
/**
* Created by RandyZhang on 2017/3/23.
*/
public class FlagExitThread extends Thread {
	public volatile Boolean isExit = false;
	public FlagExitThread(String name) {
		super(name);
	}
	@Override
	  public void run() {
		while (!isExit) {
			System.out.println("I'm running");
		}
	}
}

DemoClient.java

package com.rainmonth;
/**
* Created by RandyZhang on 2017/3/23.
*/
public class DemoClient {
	public static void main(String[] args) {
		System.out.println("优雅的终止线程实例");
		exitByFlag();
		// exitByInterrupt();
	}
	private static void exitByFlag() {
		FlagExitThread flagExitThread = new FlagExitThread(FlagExitThread.class.getSimpleName());
		flagExitThread.start();
		try {
			Thread.sleep(1000);
			flagExitThread.isExit = true;
			flagExitThread.join();
			System.out.println("线程退出");
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	private static void exitByInterrupt() {
		FlagExitThread flagExitThread = new FlagExitThread(FlagExitThread.class.getSimpleName());
		System.out.println("flagExitThread running...");
		flagExitThread.start();
		try {
			Thread.sleep(1500);
			System.out.println("flagExitThread interrupted...");
			flagExitThread.interrupt();
			Thread.sleep(1500);
			System.out.println("stop application...");
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

输出结果:

打印了一大堆I'm running之后线程退出。

2.使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。

显示调用stop()方法。源码中关于stop() 的描述如下:

/*
* This method is inherently unsafe. Stopping a thread with
* Thread.stop causes it to unlock all of the monitors that it
* has locked (as a natural consequence of the unchecked
* <code>ThreadDeath</code> exception propagating up the stack). If
* any of the objects previously protected by these monitors were in
* an inconsistent state, the damaged objects become visible to
* other threads, potentially resulting in arbitrary behavior. Many
* uses of <code>stop</code> should be replaced by code that simply
* modifies some variable to indicate that the target thread should
* stop running. The target thread should check this variable
* regularly, and return from its run method in an orderly fashion
* if the variable indicates that it is to stop running. If the
* target thread waits for long periods (on a condition variable,
* for example), the <code>interrupt</code> method should be used to
* interrupt the wait.
*/

大意就是说,该方法的不安全性时固有的。调用stop()终止一个线程会释放它已经锁定的所有监视器(这将导致沿堆栈向上传播为检查的ThreadDeath异常被抛出),若此时之前受这些被释放的监视器保护的对象存在不一致性,并且这些对象对其他线程可见,这就会导致一些意想不到的后果。stop操作应该有哪些仅仅只需要修改某些代码就可以指示目标线程应该停止运行的代码来取代(方法一就是这种方式)。如果目标线程由于等待某一条件(如某个条件变量)等待很长时间,我们应该使用interrupt方法来中断该等待(方法三就是这种方式)。

3.使用interrupt方法中断线程。

interrupt字面上是终止的意思,但不要试图通过调用interrupt来终止线程,因为有时即使你调用了该方法,线程仍然会继续执行,可以注释掉上面的exitByFlag(),开启exitByInterrupt() 方法,发现及时调用了interrupt()方法,仍在一直输出I'm running…(不同系统及CPU结果可能有所不同),可见采用interrupt方式也是不安全的。

总结

根据以上的分析,最值得推荐的方式是第一种,我们可以用共享变量(shared variable)的方式来设置标志,并发出信号,通知线程必须终止。当然对这个共享变量的操作我们必须保证是同步的。

以上就是本文关于Java终止线程实例和stop()方法源码阅读的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

Java 相关电子书
学习笔记
网友NO.529521

Java实现终止线程池中正在运行的定时任务

最近项目中遇到了一个新的需求,就是实现一个可以动态添加定时任务的功能。说到这里,有人可能会说简单啊,使用quartz就好了,简单粗暴。然而quartz框架太重了,小项目根本不好操作啊。当然,也有人会说,jdk提供了timer的接口啊,完全够用啊。但是我们项目的需求完全是多线程的模型啊,而timer是单线程的,so,楼主最后还是选择了jdk的线程池。 线程池是什么 Java通过Executors提供四种线程池,分别为: newCachedThreadPool :创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool : 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 newScheduledThreadPool : 创建一个定长线程池,支持定时及周期性任务执行。 newSingleThreadExecutor : 创建一个单线程化的线程池,它只会用……

<
1
>

Copyright 2018-2020 www.xz577.com 码农之家

版权投诉 / 书籍推广 / 赞助:520161757@qq.com