十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
java高并發(fā)系列第11篇文章。
創(chuàng)新互聯(lián)是一家專業(yè)提供北票企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站建設(shè)、H5響應(yīng)式網(wǎng)站、小程序制作等業(yè)務(wù)。10年已為北票眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進(jìn)行中。
本文主要探討一下中斷線程的幾種方式。
代碼:
package com.itsoku.chat05;
import java.util.concurrent.TimeUnit;
/**
* 微信公眾號:javacode2018,獲取年薪50萬課程
*/
public class Demo1 {
public volatile static boolean exit = false;
public static class T extends Thread {
@Override
public void run() {
while (true) {
//循環(huán)處理業(yè)務(wù)
if (exit) {
break;
}
}
}
}
public static void setExit() {
exit = true;
}
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.start();
TimeUnit.SECONDS.sleep(3);
setExit();
}
}
代碼中啟動了一個線程,線程的run方法中有個死循環(huán),內(nèi)部通過exit變量的值來控制是否退出。TimeUnit.SECONDS.sleep(3);
讓主線程休眠3秒,此處為什么使用TimeUnit?TimeUnit使用更方便一些,能夠很清晰的控制休眠時間,底層還是轉(zhuǎn)換為Thread.sleep實(shí)現(xiàn)的。程序有個重點(diǎn):volatile關(guān)鍵字,exit變量必須通過這個修飾,如果把這個去掉,程序無法正常退出。volatile控制了變量在多線程中的可見性,關(guān)于volatile前面的文章中有介紹,此處就不再說了。
示例代碼:
package com.itsoku.chat05;
import java.util.concurrent.TimeUnit;
/**
* 微信公眾號:javacode2018,獲取年薪50萬課程
*/
public class Demo2 {
public static class T extends Thread {
@Override
public void run() {
while (true) {
//循環(huán)處理業(yè)務(wù)
if (this.isInterrupted()) {
break;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.start();
TimeUnit.SECONDS.sleep(3);
t.interrupt();
}
}
運(yùn)行上面的程序,程序可以正常結(jié)束。線程內(nèi)部有個中斷標(biāo)志,當(dāng)調(diào)用線程的interrupt()實(shí)例方法之后,線程的中斷標(biāo)志會被置為true,可以通過線程的實(shí)例方法isInterrupted()獲取線程的中斷標(biāo)志。
示例代碼:
package com.itsoku.chat05;
import java.util.concurrent.TimeUnit;
/**
* 微信公眾號:javacode2018,獲取年薪50萬課程
*/
public class Demo3 {
public static class T extends Thread {
@Override
public void run() {
while (true) {
//循環(huán)處理業(yè)務(wù)
//下面模擬阻塞代碼
try {
TimeUnit.SECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.start();
}
}
運(yùn)行上面代碼,發(fā)現(xiàn)程序無法結(jié)束。
在此先補(bǔ)充幾點(diǎn)知識:
那么上面代碼可以調(diào)用線程的interrupt()方法來引發(fā)InterruptedException異常,來中斷sleep方法導(dǎo)致的阻塞,調(diào)整一下代碼,如下:
package com.itsoku.chat05;
import java.util.concurrent.TimeUnit;
/**
* 微信公眾號:javacode2018,獲取年薪50萬課程
*/
public class Demo3 {
public static class T extends Thread {
@Override
public void run() {
while (true) {
//循環(huán)處理業(yè)務(wù)
//下面模擬阻塞代碼
try {
TimeUnit.SECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
this.interrupt();
}
if (this.isInterrupted()) {
break;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.start();
TimeUnit.SECONDS.sleep(3);
t.interrupt();
}
}
運(yùn)行結(jié)果:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at com.itsoku.chat05.Demo3$T.run(Demo3.java:17)
程序可以正常結(jié)束了,分析一下上面代碼,注意幾點(diǎn):
Thread.interrupt()
方式中斷該線程,注意此時將會拋出一個InterruptedException的異常,同時中斷狀態(tài)將會被復(fù)位(由中斷狀態(tài)改為非中斷狀態(tài))