java 線程強制停止線程_java多線程之停止線程

在多線程開發中停止線程是非常重要的技術點。

停止線程在Java語言中并不像break語句那樣干脆。須要一些技巧性的處理。

一、 ?異常法

採用異常法來停止一個線程。首先我們須要了解一下兩個方法的使用方法:

1、interrupt()方法

public class MyThread extends Thread{

@Override

public void run() {

for (int i = 1; i <= 10000; i++) {

System.out.println("i="+i);

}

}

public static void main(String[] args)throws Exception {

MyThread thread=new MyThread();

thread.start();

thread.sleep(10);

thread.interrupt();

}

}

上面的樣例調用interrupt()方法來停止線程,但interrupt()方法的使用效果并不像for+break語句那樣。立即就能停止循環。

調用interrupt()方法不過在當前線程打了一個停止的標記,并非真的停止。那么假設停止線程了?我們接著往以下看。

2、推斷線程是否是停止狀態

1)、 ?interrupted()

public class MyThread extends Thread{

@Override

public void run() {

for (int i = 1; i <= 10000; i++) {

System.out.println("i="+i);

}

}

public static void main(String[] args)throws Exception {

try{

MyThread thread=new MyThread();

thread.start();

thread.sleep(100);

thread.interrupt();

System.out.println("線程停止了嗎1?--->"+thread.interrupted());

System.out.println("線程停止了嗎2?--->"+thread.interrupted());

}catch(Exception e){

e.printStackTrace();

}

System.out.println("end");

}

}Center

從控制臺打印的結果來看,線程沒有停止。這就是說,interrupted()測試當前線程是否中斷,由于這個當前線程就是main。它沒有中斷過,所以打印的結果是兩個false。

怎樣使main線程產生中斷效果了。我們在看下,以下的樣例:

public class MyThread{

public static void main(String[] args){

Thread.currentThread().interrupt();

System.out.println("線程停止了嗎1?---->"+Thread.interrupted());

System.out.println("線程停止了嗎2?---->"+Thread.interrupted());

System.out.println("end");

}

}

Center

從上面的結果來看。interrupted()方法的確推斷當前線程是否是停止狀態。

可是為什么第2個值是false。原來。連續兩次調用該方法第一次會清除中斷狀態后。第二次調用所以返回flase。

2)、 ?isInterrupted()

public class MyThread extends Thread{

@Override

public void run() {

for (int i = 1; i <= 10000; i++) {

System.out.println("i="+i);

}

}

public static void main(String[] args){

try{

MyThread thread=new MyThread();

thread.start();

thread.sleep(10);

thread.interrupt();

System.out.println("線程停止了嗎1?--->"+thread.isInterrupted());

System.out.println("線程停止了嗎2?--->"+thread.isInterrupted());

}catch(Exception e){

e.printStackTrace();

}

System.out.println("end");

}

}

d4f30196061860304a52c014280a61c4.png

從結果看出方法isInterrupted()并未清除,所以打印出了兩個true.

3、停止線程

public class MyThread extends Thread{

@Override

public void run() {

for (int i = 1; i <= 10000; i++) {

if(this.interrupted()){

System.out.println("線程是停止狀態了,我要退出了.");

break;

}

System.out.println("i="+i);

}

System.out.println("假設此處還是循環,那么我就會繼續運行.線程并沒有停止");

}

public static void main(String[] args){

try{

MyThread thread=new MyThread();

thread.start();

thread.sleep(10);

thread.interrupt();

System.out.println("end");

}catch(Exception e){

e.printStackTrace();

}

}

}

98047217b6111a28d0fc5c7b7ef7c35f.png

假設這么寫的話,線程并沒有停止。如今我們在改動下代碼。也就是所謂的異常法停止線程。

public class MyThread extends Thread{

@Override

public void run() {

try{

for (int i = 1; i <= 10000; i++) {

if(this.interrupted()){

System.out.println("線程是停止狀態了,我要退出了.");

throw new InterruptedException();

}

System.out.println("i="+i);

}

System.out.println("我被運行了嗎?");

}catch(InterruptedException e){

System.out.println("---這次線程停了---");

e.printStackTrace();

}

}

public static void main(String[] args){

try{

MyThread thread=new MyThread();

thread.start();

thread.sleep(10);

thread.interrupt();

System.out.println("end");

}catch(Exception e){

e.printStackTrace();

}

}

}

947f4bca2fe3b9c19b72ed95433dfb1d.png

二、 ?在沉睡中停止

假設線程在sleep()狀態下停止線程會有什么效果了?

public class MyThread extends Thread{

@Override

public void run() {

try{

System.out.println("run start");

Thread.sleep(1000000);

System.out.println("run end");

}catch(InterruptedException e){

System.out.println("sleep被停止,狀態:--->"+this.isInterrupted());

e.printStackTrace();

}

}

public static void main(String[] args){

try{

MyThread thread=new MyThread();

thread.start();

thread.interrupt();

thread.sleep(1000);

}catch(Exception e){

System.out.println("main catch");

e.printStackTrace();

}

}

}

d5f53bf053d3fe29525e16944c0f1c28.png

從結果我們能夠看出,在線程睡眠時候停止某一線程,會異常。而且清除停止狀態。我們前面異常停止線程,都是先睡眠,在停止線程,與之相反的操作,我寫代碼的時候須要注意下。

public class MyThread extends Thread{

@Override

public void run() {

try{

for (int i = 1; i <= 10000; i++) {

System.out.println("i="+i);

}

System.out.println("run start");

Thread.sleep(1000000);

System.out.println("run end");

}catch(InterruptedException e){

System.out.println("線程被停止了。在sleep,狀態:--->"+this.isInterrupted());

e.printStackTrace();

}

}

public static void main(String[] args){

try{

MyThread thread=new MyThread();

thread.start();

thread.interrupt();

}catch(Exception e){

System.out.println("main catch");

e.printStackTrace();

}

}

}

98fc0760bc6b04bc9a2ac133a0f2bd00.png

三、 ?暴力停止

public class MyThread extends Thread{

private int i=0;

@Override

public void run() {

try{

while (true) {

i++;

System.out.println("i="+i);

Thread.sleep(1000);

}

}catch(Exception e){

e.printStackTrace();

}

}

public static void main(String[] args){

try{

MyThread thread=new MyThread();

thread.start();

Thread.sleep(6000);

thread.stop();

}catch(Exception e){

e.printStackTrace();

}

}

}

Center

stop()方法已經被棄用,假設強制讓線程停止。能夠會有一些清理工作沒得到完畢。還有就是對鎖定的對象進行了解鎖,導致數據不同步的現象,所以開發時候禁止使用該方法去暴力停止線程。

四、 ?使用return停止線程

public class MyThread extends Thread{

private int i=0;

@Override

public void run() {

try{

while (true) {

i++;

if(this.interrupted()){

System.out.println("線程停止了");

return;

}

System.out.println("i="+i);

}

}catch(Exception e){

e.printStackTrace();

}

}

public static void main(String[] args){

try{

MyThread thread=new MyThread();

thread.start();

Thread.sleep(2000);

thread.interrupt();

}catch(Exception e){

e.printStackTrace();

}

}

}

c4a5b674ea6edbbd22f2ad3a43d6eca0.png

PS:只是還是建議使用異常法來停止線程,由于在catch塊中還能夠將異常向上拋,使線程停止事件得到傳播。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372236.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372236.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372236.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android 上下文菜單(Context Menu)

一、概述 Android中&#xff0c;上下文菜單是通過onLongClick(...)事件訪問的。在事件觸發后顯示菜單項。 在使用上下文菜單時&#xff0c;通常在onCreate(...)方法中&#xff0c;先行注冊上下文菜單。在實現onCreateContextMenu(...)方法和onContextItemSelected(...)方法。 注…

RGB顏色空間alpha混合的方法

http://blog.csdn.net/xhhjin/article/details/6444782http://blog.csdn.net/xhhjin/article/details/6445460http://www.cnblogs.com/graphics/archive/2012/08/23/2643086.htmlhttp://www.oschina.net/code/snippet_1425046_27446 轉載于:https://www.cnblogs.com/eustoma/p/…

Java怪異實踐

總覽 Java中有許多實踐使我感到困惑。 這里只是一些。 使用-Xmx和-Xms 選項-Xmx廣泛用于設置最大內存大小。 如Java HotSpot VM Options中所述&#xff0c;以-X開頭的選項是非標準的&#xff08;不保證在所有VM實現中均受支持&#xff09;&#xff0c;并且在以后的JDK發行版中…

saml java實現_java-saml

軟件簡介java-saml 是 Java 的 SAML 開發包。Maven&#xff1a;com.oneloginjava-saml2.4.0示例代碼&#xff1a;Map samlData new HashMap<>();samlData.put("onelogin.saml2.sp.entityid", "http://localhost:8080/java-saml-tookit-jspsample/metadat…

雙系統Ubuntu分區擴容過程記錄

本人電腦上安裝了Win10 Ubuntu 12.04雙系統。前段時間因為在Ubuntu上做項目要安裝一個比較大的軟件&#xff0c;導致Ubuntu根分區的空間不夠了。于是&#xff0c;從硬盤又分出來一部分空間&#xff0c;分給Ubuntu。于是有了這篇Ubuntu擴容過程記錄&#xff0c;也可以當作是一篇…

使用MongoDB的MapReduce

MapReduce是Google在2004年推出的一種軟件框架&#xff0c;用于支持對計算機集群中的大數據集進行分布式計算。 您可以從此處閱讀有關MapReduce的信息 。 MongoDB是用C 編寫的面向開源文檔的NoSQL數據庫系統。 您可以從此處閱讀有關MongoDB的更多信息。 1.安裝MangoDB。 請遵…

java epson指令集_EPSON機械手 SPEL+語言指令集

下面是全部指令的簡明列表&#xff0c;放在這里方便參考。之后重要的指令&#xff0c;勇哥要拿出來單獨學習。系統管理相關命令Reset 將控制器重置為初始狀態。SysConfig 顯示系統設置參數。SysErr 返回最新的錯誤狀態或警告狀態。Date 顯示日期。Time 顯示時間。Date$ 以字符串…

1、關于action中解決跨域請求問題:

&#xff08;1&#xff09;、action中使用ajax傳值時HttpServletRequest request ServletActionContext.getRequest(); String origin request.getHeader("Origin"); HttpServletResponse response ServletActionContext.getResponse(); response.setContentType(…

dom contains 包含關系

<!DOCTYPE html><html lang"en"><head> <meta charset"UTF-8"> <title>contains</title></head><body> <div id"p-node"> <div id"c-node">子節點內容&…

ANTLR:入門

這篇文章使您了解ANTLR的基礎知識。 以前&#xff0c;我們已經了解了如何將ANTLR設置為外部工具。 在這里&#xff1a; ANTLR外部工具 :) 所以&#xff0c;我們開始…。 什么是ANTLR&#xff1f; ?另一個語言識別工具&#xff0c;是一種語言工具&#xff0c;它提供了一個框架…

安裝JAVA8要登錄_JDK8的安裝及環境配置

原文鏈接:https://www.cnblogs.com/chenxj/p/10137221.html1、下載JDK&#xff1b;b、或百度網盤&#xff1a;鏈接&#xff1a;https://pan.baidu.com/s/1S14y4_3eN9G6oOVfhmbe_w提取碼&#xff1a;0cf62、雙擊安裝程序&#xff0c;點擊下一步安裝目錄若不修改&#xff0c;可直…

【學習筆記】JavaScript基礎(一)

【學習過程遇到疑問和延伸閱讀】 1.document.write()的深入理解write()方法可向文檔寫入HTML表達式或JavaScript代碼。可使用document.write()向輸出流寫文本或者HTML 延伸閱讀《js中document.write的那點事》http://www.cnblogs.com/dh616854836/articles/2140349.html 2.編程…

js操縱cookie技術

<% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>圖片瀏覽</title> <script typ…

java none怎么用tomcat_使用tomcat做java中間件

tomcat是一個老牌的中間件了&#xff0c;從我從業到現在時不時都會遇到它&#xff0c;方便、靈活、性能一般是我對它的使用經驗總結。配置注意 &#xff1a; tomcat 7 和 6 有很大差別&#xff0c;server.xml catalina.sh 配置文件不能通用設置tomcat7 使用jdk1.7export JAVA_H…

早期訪問中帶有NetBeans的Oracle公共云Java服務

誰期望發生這種情況&#xff1a;Oracle正在開發公共云產品&#xff0c;并且即將開始正式啟動的跡象已經出現。 在正式宣布之后將近一年&#xff0c;我被邀請加入所謂的“搶先體驗”計劃&#xff0c;以試駕新服務并提供反饋。 多虧負責產品的經理Reza Shafii &#xff0c;我才可…

MySQL 分組之后如何統計記錄條數 gourp by 之后的 count()

SELECT count(*) FROM 表名 WHERE 條件 // 這樣查出來的是總記錄條SELECT count(*) FROM 表名 WHERE 條件 GROUP BY id //這樣統計的會是每組的記錄條數.如何獲得 第二個sql語句的總記錄條數? 則是&#xff0c;如下&#xff1a;    select count(*) from(SELECT count(*) F…

python CS游戲1--角色創建,武器購買

#codingutf-8 import random 本文字主要目的是隨機創建一個角色&#xff0c;并且武器是隨機產生的&#xff0c;自帶系統給的費用10000,10000元錢可以購買武器&#xff0c;購買武器以后&#xff0c;錢會減少&#xff0c;直到不足提示無法購買 dir{"AK47":2000,"…

App Engine中的Google Services身份驗證,第2部分

在本教程的第一部分中&#xff0c; 我描述了如何使用OAuth進行Google API服務的訪問/身份驗證。 不幸的是&#xff0c;正如我稍后發現的那樣&#xff0c;我使用的方法是OAuth 1.0&#xff0c;顯然現在Google正式棄用了OAuth 1.0&#xff0c;改用OAuth 2.0版本。 顯然&#xff0…

字符串常用操作

1 常用&#xff1a;分割、長度、索引、切片2 r (1,2,3,4,5)#只讀列表元組3 name "liangml"4 strip5 username input("user:")6 if username.strip() "liangml":#strip可以將輸入前后的空格都換掉7 print("welcome")8 9 split …

java 保存bufferedimage_java - 如何將BufferedImage保存為Fi

答案在于Java Documentation的編寫/保存圖像教程。SaveImage.java類提供以下保存圖像的方法&#xff1a;static boolean ImageIO.write(RenderedImage im, String formatName, File output) throws IOException該教程解釋了這一點BufferedImage類實現RenderedImage接口。所以它…