java線程教程
① 如何使用java編寫多線程程序(1)
一、簡介1、什麼是線程要說線程,就必須先說說進程,進程就是程序的運行時的一個實例。線程呢可以看作單獨地佔有CPU時間來執行相應的代碼的。對早期的計算機(如DOS)而言,線程既是進程,進程既是進程,因為她是單線程的。當然一個程序可以是多線程的,多線程的各個線程看上去像是並行地獨自完成各自的工作,就像一台一台計算機上運行著多個處理機一樣。在多處理機計算機上實現多線程時,它們確實可以並行工作,而且採用適當的分時策略可以大大提高程序運行的效率。但是二者還是有較大的不同的,線程是共享地址空間的,也就是說多線程可以同時讀取相同的地址空間,並且利用這個空間進行交換數據。 2、為什麼要使用線程為什麼要使用多線程呢?學過《計算機體系結構》的人都知道。將順序執行程序和採用多線程並行執行程序相比,效率是可以大大地提高的。比如,有五個線程thread1, thread2, thread3, thread4, thread5,所耗的CPU時間分別為4,5,1,2,7。(假設CPU輪換周期為4個CPU時間,而且線程之間是彼此獨立的)順序執行需要花費1Array個CPU時間,而並行需要的時間肯定少於1Array個CPU時間,至於具體多少時間要看那些線程是可以同時執行的。這是在非常小規模的情況下,要是面對大規模的進程之間的交互的話,效率可以表現得更高。 3、java中是如何實現多線程的與其他語言不一樣的是,線程的觀念在java是語言中是重要的,根深蒂固的,因為在java語言中的線程系統是java語言自建的, java中有專門的支持多線程的API庫,所以你可以以最快的速度寫一個支持線程的程序。在使用java創建線程的時候,你可以生成一個Thread類或者他的子類對象,並給這個對象發送start()消息(程序可以向任何一個派生自 Runnable 介面的類對象發送 start() 消息的),這樣一來程序會一直執行,直到run返回為止,此時該線程就死掉了。在java語言中,線程有如下特點:§ 在一個程序中而言,主線程的執行位置就是main。而其他線程執行的位置,程序員是可以自定義的。值得注意的是對Applet也是一樣。 § 每個線程執行其代碼的方式都是一次順序執行的。 § 一個線程執行其代碼是與其他線程獨立開來的。如果諸線程之間又相互協作的話,就必須採用一定的交互機制。 § 前面已經說過,線程是共享地址空間的,如果控制不當,這里很有可能出現死鎖。 各線程之間是相互獨立的,那麼本地變數對一個線程而言就是完全獨立,私有的。所以呢,線程執行時,每個線程都有各自的本地變數拷貝。對象變數(instance variable)在線程之間是可以共享的,這也就是為什麼在java中共享數據對象是如此的好用,但是java線程不能夠武斷地訪問對象變數:他們是需要訪問數據對象的許可權的。二、准備知識 在分析這個例子之前,然我們先看看關於線程的幾個概念,上鎖,信號量,和java所提供的API。 上鎖對於大多數的程序而言,他們都需要線程之間相互的通訊來完成整個線程的生命周期,二實現線程之間同步的最簡單的辦法就是上鎖。為了防止相互關聯的兩個線程之間錯誤地訪問共享資源,線程需要在訪問資源的時候上鎖和解鎖,對於鎖而言,有讀鎖,寫鎖和讀寫鎖等不同的同步策略。在java中,所有的對象都有鎖;線程只需要使用synchronized關鍵字就可以獲得鎖。在任一時刻對於給定的類的實例,方法或同步的代碼塊只能被一個線程執行。這是因為代碼在執行之前要求獲得對象的鎖。 信號量通常情況下,多個線程所訪問為數不多的資源,那怎麼控制呢?一個比較非常經典而起非常簡單的辦法就是採用信號量機制。信號量機制的含義就是定義一個信號量,也就是說能夠提供的連接數;當有一個線程佔用了一個連接時,信號量就減一;當一個線程是放了連接時,信號量就加一。
② Java線程怎樣使用
多進程是指操作系統能同時運行多個任務(程序),多線程是指在同一程序中有多個順序流在執行。
在java中創建一個線程有兩種方法:
packagecom.thread;
publicclassThreadTest1{
publicstaticvoidmain(String[]args){
Runnable1r=newRunnable1();
//r.run();並不是線程開啟,而是簡單的方法調用
Threadt=newThread(r);//創建線程
//t.run();//如果該線程是使用獨立的Runnable運行對象構造的,則調用該Runnable對象的run方法;否則,該方法不執行任何操作並返回。
t.start();//線程開啟
for(inti=0;i<100;i++){
System.out.println("main:"+i);
}
}
}
{
publicvoidrun(){
for(inti=0;i<100;i++){
System.out.println("Thread-----:"+i);
}
}
}
③ java怎麼創建一個線程
Java線程類也是一個object類,它的實例都繼承自java.lang.Thread或其子類。可以用如下方式用java中創建一個線程:
Treadthread=newThread();
執行該線程可以調用該線程的start()方法:
thread.start();
編寫線程運行時執行的代碼有兩種方式:一種是創建Thread子類的一個實例並重寫run方法,第二種是創建類的時候實現Runnable介面。接下來我們會具體講解這兩種方法:
創建Thread的子類
創建Thread子類的一個實例並重寫run方法,run方法會在調用start()方法之後被執行。例子如下:
{
publicvoidrun(){
System.out.println("MyThreadrunning");
}
}
可以用如下方式創建並運行上述Thread子類
MyThreadmyThread=newMyThread();
myTread.start();
一旦線程啟動後start方法就會立即返回,而不會等待到run方法執行完畢才返回。就好像run方法是在另外一個cpu上執行一樣。當run方法執行後,將會列印出字元串MyThread running。
實現Runnable介面
第二種編寫線程執行代碼的方式是新建一個實現了java.lang.Runnable介面的類的實例,實例中的方法可以被線程調用。下面給出例子:
{
publicvoidrun(){
System.out.println("MyRunnablerunning");
}
}
為了使線程能夠執行run()方法,需要在Thread類的構造函數中傳入MyRunnable的實例對象。示例如下:
Threadthread=newThread(newMyRunnable());
thread.start();
當線程運行時,它將會調用實現了Runnable介面的run方法。上例中將會列印出」MyRunnable running」。
④ java如何實現多線程編程
1、public class MyThread extends Thread{//重寫run()方法public void run(){ //多線程要做的事}public static void main(String args[]){ MyThread m1 = new MyThread(); MyThread m2 = new MyThread(); m1.start(); m2.start();}} 2、public class NThread implements Runable{ //實現run()方法 public void run(){ //多線程要做的事 } public static void main(String args[]){ NThread nt = new NThread(); new Thread(nt,"nt1_name").start(); new Thread(nt,"nt2_name").start(); }}
⑤ Java線程的概念與原理
一 操作系統中線程和進程的概念
兄缺現在的操作系統是多任務操作系統 多線程是實現多任務的一種方式
進程是指一個內存中運行的應用程序 每個進程都有自己獨立的一塊內存空間 一個進程中可以啟動多個線程 比如在Windows系統中 一個運行的exe就是一個進程 線程是指進程中的一個執行流程 一個進程中可以運行多個線程 比如java exe進程中可以運行很多線程 線程總是屬於某羨畢辯個進程 進程中的多個線程共享進程的內存 同時 執行是人的感覺 在線程之間實際上輪換執行
二 Java中的線程
在Java中 線程 指兩件不同的事情
java lang Thread類的一個實例
線程的執行
使用java lang Thread類或者java lang Runnable介面編寫代碼來定義 實例化和啟動新線程 一個Thread類實例只是一個對象 像Java中的任何其他對象一樣 具有變數和方法 生死於堆上 Java中 每個線程都有一個調用棧 即使不在程序中創建任何新的線程 線程也在後台運行著 一個Java應用總是從main()方法開始運行 mian()方法運行在一個線程內 它被稱為主線程 一旦創建一個新的線程 就產生一個新的調用棧 線程總體分兩類 用戶線程和守候線程
當所有用戶線程執行完畢的時候 JVM自動關閉 但是守候線程卻不獨立於JVM 守候線程一般是由操作系統或者用戶自己創建的
———————————MultiT java——————————————————————
class MultiThread
{
public static void main(String[] args)
{
MyThread mt=new MyThread();
//mt setDaemon(true);//設定為後台線程 main進程結束時 後台進程也跟著結束
//mt setPriority(Thread MAX_PRIORITY); //設定線程優先順序 MAX_PRIORITY為 MIN_PRIORITY為 NORM_PRIORITY為
//設定為最高優先順序後 程序運行時 mt線程一直運行 強制終止時 main線程才運行
//設定為最高優先順序的線程 無論有無yield(); 線程總一直運行 直到強制終止時 main和mt線程交替運行
mt start();
int index= ;
while(true) //顯示結果與教程不同
{
if(index++== )
break;
System out println( main: +Thread currentThread() getName()); //獲取線程名字
}
}
}
class MyThread extends Thread
{
public void run()
{
while(true)
{
System out println(getName());
yield(); //允許當前線程停止 轉去執行其他線程 靜態方法
//mt進程執行時 切換到main進程 main進程執行一段時間數帆後
//切換進程到mt mt執行完獲取名字後 返回到main進程
}
}
}
//一個長時間處於等待狀態的線程也有可能被線程調度器調度 從而運行
//打破高優先順序線程始終獲有運行時間的狀態
——————————————————————————————————————
——————————MultiThread java———————————————————————
class MultiThread
{
public static void main(String[] args)
{
MyThread mt=new MyThread();
//new Thread(mt) start(); //創建多個同樣的線程訪問同一個變數index 若MyThread採用繼承Thread方式 則無法共享同一個變數
//new Thread(mt) start();
//new Thread(mt) start();
//new Thread(mt) start();
mt getThread() start(); //也可以採用內部類的方式共享訪問同一個變數
mt getThread() start();
mt getThread() start();
mt getThread() start();
//mt setDaemon(true);//設定為後台線程 main進程結束時 後台進程也跟著結束
//mt setPriority(Thread MAX_PRIORITY); //設定線程優先順序 MAX_PRIORITY為 MIN_PRIORITY為 NORM_PRIORITY為
//設定為最高優先順序後 程序運行時 mt線程一直運行 強制終止時 main線程才運行
//設定為最高優先順序的線程 無論有無yield(); 線程總一直運行 直到強制終止時 main和mt線程交替運行
//mt start();
int index= ;
while(true) //顯示結果與教程不同
{
// if(index++== )
// break;
System out println( main: +Thread currentThread() getName()); //獲取線程名字
}
}
}
class MyThread //implements Runnable //extends Thread //使用外部類的方式
//使用內部類完成使用Runnable介面才能完成的兩個功能 a 創建多個線程 b 訪問同一個變數
{
int index= ;
private class InnerThread extends Thread //不想讓外部訪問其實現方法 加上private
{
public void run()
{
while(true)
{
System out println(Thread currentThread() getName()+ : +index++);
}
}
}
Thread getThread()
{
return new InnerThread();
}
/*
public void run()
{
while(true)
{
System out println(Thread currentThread() getName()+ : +index++);
//yield(); //允許當前線程停止 轉去執行其他線程 靜態方法
//mt進程執行時 切換到main進程 main進程執行一段時間後
//切換進程到mt mt執行完獲取名字後 返回到main進程
}
}
*/
}
//一個長時間處於等待狀態的線程也有可能被線程調度器調度 從而運行
//打破高優先順序線程始終獲有運行時間的狀態
//如果不需要修改Thread類的除了run方法外的其他方法 選用implements Runnable
———————————————————————————————————————
———————————TicketsSystem java———————————————————
//多線程實現火車票的售票系統 用同步塊 或著同步方法
class TicketsSystem
{
public static void main(String[] args) //運行結果與教程中不同 不完全順序 每次運行 順序都不完全一樣
{
SellThread st=new SellThread();//創建四個線程訪問同一變數tickets
// 錯 SellThread st =new SellThread();//若採用創建四個對象的方式 則每個對象中都有 張票
new Thread(st) start(); //b為false 用的同步方法 | //同步方法與同步塊共用中 顯示的是只調用了同步塊 而同步方法未被調用
//b為true 用的同步塊 | //原因 啟動第一個線程後 CPU時間片沒有到期 線程沒有立即運行 接著執行b=true
// | //解決辦法 啟動第一個線程後 執行一個睡眠時間 讓CPU時間片到期
try
{
Thread sleep( );
}
catch(Exception e)
{
e printStackTrace();
}
st b=true;
new Thread(st) start();
//new Thread(st) start();
//new Thread(st) start();
}
}
class SellThread implements Runnable //程序有點小問題 當剩下最後一張票時 四個線程都運行 可能會出現票數為 (系統長時間運行時)
//可加上一個靜態方法sleep();它會拋出異常
{
int tickets= ;
//Object obj=new Object();//也可以聲明一個Thread對象
Thread th=new Thread();
boolean b=false;
public void run()
{
if(b==false)
{
while(true)
sell();
}
else
{
while(true)
{ //同步方法利用的是this所代表的對象的鎖
synchronized(this) //採用同步後 顯示正確 此方法兩步 聲明Thread對象 用synchronized把原方法括起來
{ //這里換th為this
///*
if(tickets> )
{
try
{
Thread sleep( );
}
catch(Exception e)
{
e printStackTrace();
}
System out println( th +Thread currentThread() getName()+ sell tickets: +tickets);
tickets ;
}
//*/
}
}
}
}
public synchronized void sell() //每個class也有一個鎖 是這個class所對應的class對象的鎖(監視器)
{
if(tickets> )
{
try
{
Thread sleep( );
}
catch(Exception e)
{
e printStackTrace();
}
System out println( sell +Thread currentThread() getName()+ sell tickets: +tickets);
tickets ;
}
}
}
————————————————————————————————————————
———————————TestWN java————————————————————
class Test
{
public static void main(String[] args)
{
Queue q=new Queue();
Procer p=new Procer(q);
Consumer c=new Consumer(q);
p start();
c start();
}
}
class Procer extends Thread
{
Queue q;
Procer(Queue q)
{
this q=q;
}
public void run()
{
for(int i= ;i< ;i++)
{
q put(i);
System out println( Procer put: +i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this q=q;
}
public void run()
{
while(true)
{
System out println( Consumer get: +q get());
}
}
}
class Queue //wait notify 方法必須用在同步方法中 要加上關鍵字synchronized
{
int value;
boolean bFull=false;
public synchronized void put(int i)
{
if(!bFull)
{
value=i;
bFull=true;
notify();
}
try
{
wait();
}
catch(Exception e)
{
e printStackTrace();
}
}
public synchronized int get()
{
if(!bFull)
{
try
{
wait();
}
catch(Exception e)
{
e printStackTrace();
}
}
bFull=false;
notify();
return value;
}
}
————————————————————————————————————
————————————TestThread java———————————————————————
class TestThread
{
public static void main(String[] args)
{
Thread t =new Thread ();
t start();
int index= ;
while(true)
{
if(index++== )
{
t stopThread();
t interrupt(); //讓線程 終止
break;
}
System out println(Thread currentThread() getName());
}
System out println( main() exit );
}
}
class Thread extends Thread
{
private boolean bStop=false;
public synchronized void run()
{
while(!bStop)
{
try
{
wait(); //加入wait後 main線程結束時 程序還未終止 原因是Thread 的線程調用wait方法 進入對象的等待隊列中 需要notify方法將它喚醒
}
catch(Exception e)
{
//e printStackTrace();
if(bStop)
return;
}
System out println(getName());
}
}
public void stopThread()
{
bStop=true;
}
}
lishixin/Article/program/Java/gj/201311/27407
⑥ java入門教程什麼好java入門教程學習
java入門教程學習應從介紹java常用語開始,據了解,Java設計開發小組的成員總結了一些關鍵因素,稱其為Java的專門用語,包括下面幾個:
一、簡單
Java設計目的是讓專業程序員覺得既易學又好用。如果你已經理解面向對象編程的基本概念,學習Java將更容易。如果你是一個經驗豐富的C++程序員,那就最好了,學習Java簡直不費吹灰之力。因為Java承C/C++語法和許多C++面向對象的特性,大多數程序員在學習Java時都不會覺得太難。另外,C++中許多容易混淆的概念,或者被Java棄之不用了,或者以一種更清楚、更易理解的方式實現。
除了和C/C++類似以外,Java的另外一個屬性也使它更容易學習:設計人員努力使Java中不出現顯得讓人吃驚的特性。在Java中,很少明確地告訴你如何才能完成一項特定的任務。
二、面向對象
盡管受到其前輩的影響,但Java沒被設計成兼容其他語言源代碼的程序。這允許Java開發組自由地從零開始。
這樣做的一個結果是,Java語言可以更直接、更易用、更實際的接近對象。通過對近幾十年面向對象軟體優點的借鑒,Java設法在純進化論者的「任何事物都是一個對象」和實用主義者的「不討論對象不對象」的論點之間找到了平衡。Java的對象模型既簡單又容易擴展,對於簡單數據類型,例如整數,它保持了高性能,但腔悉不是對象。
三、健壯
為更好理解Java是如何具有健壯性的,讓我們考慮使程序失敗的兩個主要原因:內存管理錯誤和誤操作引起的異常情況(也就是運行時錯誤)。在傳統的伍蠢乎編程環境下,內存管理是一項困難、乏味的任務。在傳統的環境下,異常情況可能經常由「被零除」或「文件未找到」這樣的情況引起,而我們又必須用既繁多又難以理解的一大堆指令來對它們進行管理。
四、多線程
設計Java的目標之一是為了滿足人們對創建互動式網上程序的需要。為此,Java支持多線程編程,因而你用Java編寫的應用程序可以同時執行多個任務。Java運行時系統在多線程同步方面具有成熟的解決方案,這使你能夠創建出運行平穩的互動式系統。Java的多線程機制非常好用,因而你只需關注程序細節的實現,不用擔心後台的多任務系統。
五、結構中立
Java設計者考慮的一個主要問題是程序代碼的持久性和可移植性。程序員面臨的一個主要問題是,不能保證今天編寫的程序明天能否在同一台機器上順利運行。操作系統升級、處理器升級以及核心系統資源的變化,都可能導致程序無法繼續運行。Java設計者對這個問題做過多種嘗試,Java虛擬機(JVM)就是試圖解決這個問題的。他們的目標是「只要寫一次程序,在任何地方、任何時間該程序永遠都能運行」。在很大程度上,Java實現了這個目標。
六、解釋性和高性能
前面已解釋過,Java確實是一種解釋性語言,Java的位元組碼經過仔細設計,因而很容易便能使用JIT編譯技術將位元組碼直接轉換成高性能的本機代碼。Java運行時系統在提供這個特性的同時仍具有平台獨立性,因而「高效且跨平台」對Java來說不再矛盾。
七、分布式
事實上,通過URL地址存取資源與直接存取一個文件的差別是不太大的。Java原來的版本(Oak)包括了內置的地址空格消息傳遞(intra-address-space)特性。這允許位於兩台不同的計算機上的對象可以遠程地執行過程。
八、動態
Java程序帶有多種的運行時類型信息,用於在運行時校驗和解決對象訪檔伏問問題。這使得在一種安全、有效的方式下動態地連接代碼成為可能,對小應用程序環境的健壯性也十分重要,因為在運行時系統中,位元組碼內的小段程序可以動態地被更新。