線 程
前面我們所給出的程序例子,基本都是單線程的,即一個程序只有一條從頭到尾的執行路線,然後在程序設計中,很多的時候,我們需要編寫具有多線程的程序。這也就是今天要給大家說的線程的問題了。
多現成是指同時存在幾個執行體,按幾條不同的執行路線共同工作的情況。Java語言中,有一個重要的功能特點就是它的內置對多線程的支持,它使的變成人員可以很方便地開發出具有多線程功能,能同時處理多個任務的功能強大的應用程序。
一 .Java線程的幾個概念
1)程序,進程與線程的關系
程序是一段靜態的代碼,它是應用軟件執行的根本。
進程是程序的一次動態執行過程,它對應了從代碼加載、執行到執行完畢的一個完整過程,這個過程也是進程本身從產生、發展到消亡的過程。做為執行藍本的同一段程序,可以被加載到系統的不同內存區域分別執行,形成不同的進程。
線程是比進程更小的執行單位。一個進程在其執行過程能夠中,可以產生 多個線程,形成多條執行線索。每條線索,即每個線程也有它自身的產生、存在和消亡過程,也是一個動態的概念。
2)線程的轉台與生命周期
每個Java程序都有一個缺省的主線程,對於Application,主線程是main()方法執行的線索,對於Applet,主線程指揮浏覽器加載並執行Java小程序。要想實現多線程,必須在主現成中創建新的現成對象。Java語言使用Thread類及其自類的對象來表示線程,新建的線程在它的一個完整的生命周期中通常要經歷如下的五種狀態:
新建:新生的線程對象出新建狀態,此時,它已經有了相應的內存空間和其他資源,並已經被初始化。
就緒:處於新建狀態的線程被啟動後,將進入線程隊列排隊等待CPU時間片,此時它已經具備了運行的條件。一旦輪到它來享用CPU資源時,它就可以脫離創建它的主線程而單獨開始自己的生命周期了。另外,原來處於阻塞狀態的線程被接觸阻塞後也將進入就緒狀態。
運行:當就緒狀態的線程被調度並獲得處理器資源時,便進入運行狀態。
阻塞:一個正在執行的線程在某些特殊情況下,讓出CPU並暫時終止自己的執行,進入睡眠狀態。
死亡:處於死亡狀態的纖塵不具有繼續運行的能力。線程死亡的原因有兩個:一個是正常運行的現成完成它的全部工作後退出。另外的一個則是線程提前強制性地終止,如通過執行stop()方法或destroy()來終止線程。
好了,說了這麼多,還是給大家舉幾個例子,配合例子給大家講講線程的始末吧!
二 .Java線程的例子
這個例子只是向大家說明在系統的內部,兩個毫不干涉的線程個自執行的情況。從這個例子可以看到每個現成各自執行了多少次!
點擊這兒查看源代碼及解釋
一個時鐘的例子
源代碼如下:
import Java.awt.*;
import Java.applet.*;
import java.util.Date; //這是Java中的低級實用工具包,可以處理時間等內容。
public class Applet1 extends Applet implements Runnable //有線程運行接口
{
Date timenow; //Date是一個時間定義與創建函數.
Clock myClock; //用戶自定義的類
Thread clockthread=null; //設置一個線程
public void start() //線程開始的類
{
if (clockthread==null) //如果線程為空,則
{
clockthread=new Thread (this); //開始新的線程
clockthread.start(); //開始
}
}
public void stop() //終止線程
{
clockthread.stop(); //終止線程,使它
clockthread=null; //為空
}
public void run() //運行線程
{
while(true) //一個死循環,條件永遠都是真的。
{
repaint(); //重新繪制界面
try{Thread.sleep(1000);} //讓線程沉睡1000毫秒,也就是一秒鐘
catch(InterruptedException e){} //捕獲異常(也就是錯誤)
}
}
public void paint(Graphics g)
{
timenow=new Date(); //新的時間的獲得
//獲得小時,分鐘,秒鐘
myClock=new Clock(timenow.getHours (),
timenow.getMinutes (),
timenow.getSeconds ());
g.drawString(timenow.toString(),25,240);//將它打印出來!
myClock.show(g,100,100,100); //使面板顯示
}
}
class Clock //用戶自定義的類開始,編譯後,它單獨成為一個CLASS文件
{
Clock(int hrs,int min,int sec) //類函數入口
{
hour=hrs%12; //將原始數據處理,得到小時
minute=min; //將原始數據處理,得到分鐘
second=sec; //將原始數據處理,得到小時
}
void show(Graphics g,int cx,int cy,int rad) //重新定義SHOW函數
{
int hrs_len=(int)(rad*0.5), //時針的長度
min_len=(int)(rad*0.6), //分鐘的長度
sec_len=(int)(rad*0.9); //秒鐘的長度
double theta;
//畫出鐘面
g.drawOval(cx-rad,cy-rad,rad*2,rad*2);
//畫出時針
theta=(double)(hour*60*60+minute*60+second)/43200.0*2.0*Math.PI ;
drawNiddle(g,Color.blue,cx,cy,hrs_len,theta);
//畫出分針
theta=(double)(minute*60+second)/3600.0*2.0*Math.PI ;
drawNiddle(g,Color.red,cx,cy,sec_len,theta);
//畫出秒針
theta=(double)(second)/60.0*2.0*Math.PI ;
drawNiddle(g,Color.green ,cx,cy,sec_len,theta);
}
private void drawNiddle(Graphics g,Color c,int x,int y,int len,double theta)
{
int ex=(int)(x+len*Math.sin(theta));
int ey=(int)(y-len*Math.cos(theta));
g.setColor (c);
g.drawLine(x,y,ex,ey);
}
int hour,minute,second;