在java程序中,可以使用java.lang.System的exit方法來終止程序的執(zhí)行,publicstaticvoidmain(String[]args){System.out.println("開始進(jìn)入程序");//dosomethingSystem.out.println("程序準(zhǔn)備退出了!");System.exit(0);//下面這句話將
成都創(chuàng)新互聯(lián)是一家專注于成都做網(wǎng)站、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),莆田網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:莆田等地區(qū)。莆田做網(wǎng)站價(jià)格咨詢:13518219792
終止線程的三種方法:
1. 使用退出標(biāo)志,使線程正常退出,也就是當(dāng)run方法完成后線程終止。?
2. 使用stop方法強(qiáng)行終止線程(這個(gè)方法不推薦使用,因?yàn)閟top和suspend、resume一樣,也可能發(fā)生不可預(yù)料的結(jié)果)。
3. 使用interrupt方法中斷線程。?
1. 使用退出標(biāo)志終止線程?
當(dāng)run方法執(zhí)行完后,線程就會(huì)退出。但有時(shí)run方法是永遠(yuǎn)不會(huì)結(jié)束的。如在服務(wù)端程序中使用線程進(jìn)行監(jiān)聽客戶端請(qǐng)求,或是其他的需要循環(huán)處理的任務(wù)。在這種情況下,一般是將這些任務(wù)放在一個(gè)循環(huán)中,如while循環(huán)。如果想讓循環(huán)永遠(yuǎn)運(yùn)行下去,可以使用while(true){……}來處理。但要想使while循環(huán)在某一特定條件下退出,最直接的方法就是設(shè)一個(gè)boolean類型的標(biāo)志,并通過設(shè)置這個(gè)標(biāo)志為true或false來控制while循環(huán)是否退出。下面給出了一個(gè)利用退出標(biāo)志終止線程的例子。?
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("線程退出!");?
}?
}
在上面代碼中定義了一個(gè)退出標(biāo)志exit,當(dāng)exit為true時(shí),while循環(huán)退出,exit的默認(rèn)值為false.在定義exit時(shí),使用了一個(gè)Java關(guān)鍵字volatile,這個(gè)關(guān)鍵字的目的是使exit同步,也就是說在同一時(shí)刻只能由一個(gè)線程來修改exit的值,?
2. 使用stop方法終止線程?
使用stop方法可以強(qiáng)行終止正在運(yùn)行或掛起的線程。我們可以使用如下的代碼來終止線程:?
thread.stop();?
雖然使用上面的代碼可以終止線程,但使用stop方法是很危險(xiǎn)的,就象突然關(guān)閉計(jì)算機(jī)電源,而不是按正常程序關(guān)機(jī)一樣,可能會(huì)產(chǎn)生不可預(yù)料的結(jié)果,因此,并不推薦使用stop方法來終止線程。?
3. 使用interrupt方法終止線程?
使用interrupt方法來終端線程可分為兩種情況:?
(1)線程處于阻塞狀態(tài),如使用了sleep方法。?
(2)使用while(!isInterrupted()){……}來判斷線程是否被中斷。?
在第一種情況下使用interrupt方法,sleep方法將拋出一個(gè)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秒之內(nèi)按任意鍵中斷線程!");?
System.in.read();?
thread.interrupt();?
thread.join();?
System.out.println("線程已經(jīng)退出!");?
}?
}
上面代碼的運(yùn)行結(jié)果如下:?
在50秒之內(nèi)按任意鍵中斷線程!?
sleep interrupted?
線程已經(jīng)退出!?
在調(diào)用interrupt方法后, sleep方法拋出異常,然后輸出錯(cuò)誤信息:sleep interrupted.?
注意:在Thread類中有兩個(gè)方法可以判斷線程是否通過interrupt方法被終止。一個(gè)是靜態(tài)的方法interrupted(),一個(gè)是非靜態(tài)的方法isInterrupted(),這兩個(gè)方法的區(qū)別是interrupted用來判斷當(dāng)前線是否被中斷,而isInterrupted可以用來判斷其他線程是否被中斷。因此,while (!isInterrupted())也可以換成while (!Thread.interrupted())。
如下:
import?java.awt.*;
import?java.awt.event.*;
import?javax.swing.JButton;
import?javax.swing.JFrame;
import?javax.swing.JPanel;
import?javax.swing.Timer;
import?java.awt.geom.*;
import?java.util.*;
class?Clock?extends?Canvas
implements?ActionListener{
static??JButton?jb=new?JButton("開始");
static?JButton?jb1=new?JButton("暫停");
Date?date;
Timer?secondTime;
int?hour,munite,second;
Line2D?secondLine,muniteLine,hourLine;
int?a,b,c;
double?pointSX[]=new?double[60],//用來表示秒針端點(diǎn)坐標(biāo)的數(shù)組
pointSY[]=new?double[60],
pointMX[]=new?double[60],?//用來表示分針端點(diǎn)坐標(biāo)的數(shù)組
pointMY[]=new?double[60],
pointHX[]=new?double[60],?//用來表示時(shí)針端點(diǎn)坐標(biāo)的數(shù)組
pointHY[]=new?double[60];
Clock()
{?secondTime=new?Timer(1000,this);
pointSX[0]=0;?????????????????????????//12點(diǎn)秒針位置
pointSY[0]=-100;
pointMX[0]=0;?????????????????????????//12點(diǎn)分針位置
pointMY[0]=-90;
pointHX[0]=0;?????????????????????????//12點(diǎn)時(shí)針位置
pointHY[0]=-70;
double?angle=6*Math.PI/180;??????????//刻度為6度
for(int?i=0;i59;i++)????????????????//計(jì)算出各個(gè)數(shù)組中的坐標(biāo)
{?pointSX[i+1]=pointSX[i]*Math.cos(angle)-Math.sin(angle)*pointSY[i];
pointSY[i+1]=pointSY[i]*Math.cos(angle)+pointSX[i]*Math.sin(angle);
pointMX[i+1]=pointMX[i]*Math.cos(angle)-Math.sin(angle)*pointMY[i];
pointMY[i+1]=pointMY[i]*Math.cos(angle)+pointMX[i]*Math.sin(angle);
pointHX[i+1]=pointHX[i]*Math.cos(angle)-Math.sin(angle)*pointHY[i];
pointHY[i+1]=pointHY[i]*Math.cos(angle)+pointHX[i]*Math.sin(angle);
}
for(int?i=0;i60;i++)
{?pointSX[i]=pointSX[i]+120;????????????//坐標(biāo)平移
pointSY[i]=pointSY[i]+120;
pointMX[i]=pointMX[i]+120;????????????//坐標(biāo)平移
pointMY[i]=pointMY[i]+120;
pointHX[i]=pointHX[i]+120;????????????//坐標(biāo)平移
pointHY[i]=pointHY[i]+120;
}
secondLine=new?Line2D.Double(0,0,0,0);
muniteLine=new?Line2D.Double(0,0,0,0);
hourLine=new?Line2D.Double(0,0,0,0);
secondTime.start();????????//秒針開始計(jì)時(shí)
}
public?void?paint(Graphics?g)
{???for(int?i=0;i60;i++)?????//繪制表盤上的小刻度和大刻度
{??int?m=(int)pointSX[i];
int?n=(int)pointSY[i];
if(i%5==0)
{?g.setColor(Color.red);
g.fillOval(m-4,n-4,8,8);
}
else
{?g.setColor(Color.cyan);
g.fillOval(m-2,n-2,4,4);
}
}
g.fillOval(115,115,10,10);??//鐘表中心的實(shí)心圓
Graphics2D?g_2d=(Graphics2D)g;
g_2d.setColor(Color.red);
g_2d.draw(secondLine);
BasicStroke?bs=
new?BasicStroke(3f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
g_2d.setStroke(bs);
g_2d.setColor(Color.blue);
g_2d.draw(muniteLine);
bs=new?BasicStroke(6f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER);
g_2d.setStroke(bs);
g_2d.setColor(Color.green);
g_2d.draw(hourLine);
}
public?void?actionPerformed(ActionEvent?e)
{?if(e.getSource()==secondTime){
date=new?Date();
String?s=date.toString();
hour=Integer.parseInt(s.substring(11,13));
munite=Integer.parseInt(s.substring(14,16));
second=Integer.parseInt(s.substring(17,19));?//獲取時(shí)間中的秒
int?h=hour%12;
a=second;????????????????????//秒針端點(diǎn)的坐標(biāo)
b=munite;????????????????????//分針端點(diǎn)的坐標(biāo)
c=h*5+munite/12;?????????????//時(shí)針端點(diǎn)的坐標(biāo)
secondLine.setLine(120,120,(int)pointSX[a],(int)pointSY[a]);
muniteLine.setLine(120,120,(int)pointMX[b],(int)pointMY[b]);
hourLine.setLine(120,120,(int)pointHX[c],(int)pointHY[c]);
repaint();
}?if(e.getSource()==jb){
?secondTime.start();
}if(e.getSource()==jb1){
?secondTime.stop();
}
}
public?static?void?main(String?args[]){
?JFrame?win=new?JFrame("時(shí)鐘");
?JPanel?jp=new?JPanel();
?jp.add(jb);
?jp.add(jb1);
?Clock?clock=new?Clock();
?jb.addActionListener(clock);
?jb1.addActionListener(clock);
?win.add(clock,BorderLayout.CENTER);
?win.add(jp,"South");
?win.setVisible(true);
?win.setSize(246,300);
?win.setDefaultCloseOperation(3)?;
?win.validate();
???}
}
運(yùn)行截圖:
有問題就追問,滿意請(qǐng)采納。
在Java中,拋出異常之后,如果不對(duì)異常進(jìn)行處理,代碼會(huì)一直往調(diào)用的上層拋,直到線程的執(zhí)行器,如果在這里異常仍然未得到處理,線程將停止執(zhí)行。所以拋出異常后如果不對(duì)異常進(jìn)行處理,后面的代碼將不會(huì)執(zhí)行。
比如以下代碼:
public void testException throws Exception(){
System.out.println("start");
throw new Exception("test exception");
System.out.println("execute ended?");
}
最后一行代碼在異常拋出之后,這行代碼是不會(huì)執(zhí)行的。