1. 程式人生 > >runnable和thread的區別以及run和start的區別(多執行緒)

runnable和thread的區別以及run和start的區別(多執行緒)

在java中可有兩種方式實現多執行緒,一種是繼承Thread類,一種是實現Runnable介面;Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多執行緒操作了,但是一個類只能繼承一個父類,這是此方法的侷限。

下面看例子:

  1. package org.thread.demo;  
  2. class MyThread extends Thread{  
  3. private String name;  
  4. public MyThread(String name) {  
  5. super();  
  6. this.name = name;  
  7. }  
  8. publicvoid
     run(){  
  9. for(int i=0;i<10;i++){  
  10. System.out.println("執行緒開始:"+this.name+",i="+i);  
  11. }  
  12. }  
  13. }  
  14. package org.thread.demo;  
  15. publicclass ThreadDemo01 {  
  16. publicstaticvoid main(String[] args) {  
  17. MyThread mt1=new MyThread("執行緒a");  
  18. MyThread mt2=new MyThread("執行緒b");  
  19. mt1.run();  
  20. mt2.run();  
  21. }  

但是,此時結果很有規律,先第一個物件執行,然後第二個物件執行,並沒有相互執行。在JDK的文件中可以發現,一旦呼叫start()方法,則會通過JVM找到run()方法。下面啟動start()方法啟動執行緒:

  1. package org.thread.demo;  
  2. publicclass ThreadDemo01 {  
  3. publicstaticvoid main(String[] args) {  
  4. MyThread mt1=new MyThread("執行緒a");  
  5. MyThread mt2=new MyThread("執行緒b");  
  6. mt1.start();  
  7. mt2.start();  
  8. }  
  9. }; 

這樣程式可以正常完成互動式執行。那麼為啥非要使用start();方法啟動多執行緒呢?

在JDK的安裝路徑下,src.zip是全部的java源程式,通過此程式碼找到Thread中的start()方法的定義,可以發現此方法中使用了private native void start0();其中native關鍵字表示可以呼叫作業系統的底層函式,那麼這樣的技術成為JNI技術(java Native Interface)

Runnable介面

在實際開發中一個多執行緒的操作很少使用Thread類,而是通過Runnable介面完成。

  1. publicinterface Runnable{  
  2. publicvoid run();  

例子:

  1. package org.runnable.demo;  
  2. class MyThread implements Runnable{  
  3. private String name;  
  4. public MyThread(String name) {  
  5. this.name = name;  
  6. }
  7. publicvoid run(){  
  8. for(int i=0;i<100;i++){  
  9. System.out.println("執行緒開始:"+this.name+",i="+i);  
  10. }  
  11. }  
  12. }; 

但是在使用Runnable定義的子類中沒有start()方法,只有Thread類中才有。此時觀察Thread類,有一個構造方法:public Thread(Runnable targer)此構造方法接受Runnable的子類例項,也就是說可以通過Thread類來啟動Runnable實現的多執行緒。(start()可以協調系統的資源):

  1. package org.runnable.demo;  
  2. import org.runnable.demo.MyThread;  
  3. publicclass ThreadDemo01 {  
  4. publicstaticvoid main(String[] args) {  
  5. MyThread mt1=new MyThread("執行緒a");  
  6. MyThread mt2=new MyThread("執行緒b");  
  7. new Thread(mt1).start();  
  8. new Thread(mt2).start();  
  9. }  

兩種實現方式的區別和聯絡:

在程式開發中只要是多執行緒肯定永遠以實現Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下好處:

  • 避免點繼承的侷限,一個類可以繼承多個介面。
  • 適合於資源的共享

以賣票程式為例,通過Thread類完成:

  1. package org.demo.dff;  
  2. class MyThread extends Thread{  
  3. privateint ticket=10;  
  4. publicvoid run(){  
  5. for(int i=0;i<20;i++){  
  6. if(this.ticket>0){  
  7. System.out.println("賣票:ticket"+this.ticket--);  
  8. }  
  9. }  
  10. }  
  11. }; 

下面通過三個執行緒物件,同時賣票:

  1. package org.demo.dff;  
  2. publicclass ThreadTicket {  
  3. publicstaticvoid main(String[] args) {  
  4. MyThread mt1=new MyThread();  
  5. MyThread mt2=new MyThread();  
  6. MyThread mt3=new MyThread();  
  7. mt1.start();//每個執行緒都各賣了10張,共賣了30張票
  8. mt2.start();//但實際只有10張票,每個執行緒都賣自己的票
  9. mt3.start();//沒有達到資源共享
  10. }  

如果用Runnable就可以實現資源共享,下面看例子:

  1. package org.demo.runnable;  
  2. class MyThread implements Runnable{  
  3. privateint ticket=10;  
  4. publicvoid run(){  
  5. for(int i=0;i<20;i++){  
  6. if(this.ticket>0){  
  7. System.out.println("賣票:ticket"+this.ticket--);  
  8. }  
  9. }  
  10. }  
  11. }  
  12. package org.demo.runnable;  
  13. publicclass RunnableTicket {  
  14. publicstaticvoid main(String[] args) {  
  15. MyThread mt=new MyThread();  
  16. new Thread(mt).start();//同一個mt,但是在Thread中就不可以,如果用同一
  17. new Thread(mt).start();//個例項化物件mt,就會出現異常
  18. new Thread(mt).start();  
  19. }  
  20. }; 

雖然現在程式中有三個執行緒,但是一共賣了10張票,也就是說使用Runnable實現多執行緒可以達到資源共享目的。

Runnable介面和Thread之間的聯絡:

public class Thread extends Object implements Runnable

發現Thread類也是Runnable介面的子類。

總結:runnable的工作並行,一起做一個任務。thread序列,各自做自己的。

start並行,交替工作。而run序列,順序工作,上面做完下面才做

相關推薦

runnablethread區別以及runstart區別執行

在java中可有兩種方式實現多執行緒,一種是繼承Thread類,一種是實現Runnable介面;Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多執行緒操作了,但是一個類只能繼承一個父類,這是此方法的

Qt:Qt實現Winsock網路程式設計—TCP服務端客戶端通訊執行

Qt實現Winsock網路程式設計—TCP服務端和客戶端通訊(多執行緒) 前言 感覺Winsock網路程式設計的api其實和Linux下網路程式設計的api非常像,其實和其他程式語言的網路程式設計都差不太多。博主用Qt實現的,當然不想用黑視窗唄,有介面可以看到,由於GUI程式設計

java架構之路執行JMMvolatile關鍵字

  貌似兩個多月沒寫部落格,不知道年前這段時間都去忙了什麼。   好久以前寫過一次和volatile相關的部落格,感覺沒寫的那麼深入吧,這次我們繼續說我們的volatile關鍵字。 複習:   先來簡單的複習一遍以前寫過的東西,上次我們說了記憶體一致性協議M(修改)E(獨佔)S(共享)I(失效)四種狀態,還有

java架構之路執行AQS之ReetrantLock顯示鎖的使用底層原始碼解讀

  說完了我們的synchronized,這次我們來說說我們的顯示鎖ReetrantLock。 上期回顧:   上次部落格我們主要說了鎖的分類,synchronized的使用,和synchronized隱式鎖的膨脹升級過程,從無鎖是如何一步步升級到我們的重量級鎖的,還有我們的逃逸分析。 鎖的粗化和鎖的消除  

java架構之路執行synchronized詳解以及鎖的膨脹升級過程

  上幾次部落格,我們把volatile基本都說完了,剩下的還有我們的synchronized,還有我們的AQS,這次部落格我來說一下synchronized的使用和原理。   synchronized是jvm內部的一把隱式鎖,一切的加鎖和解鎖過程是由jvm虛擬機器來控制的,不需要我們認為的干預,我們大致從瞭

Runablethread區別執行必須用Runable

看到一個面試題.問兩種實現多執行緒的方法.沒事去網上找了找答案.  網上流傳很廣的是一個網上售票系統講解.轉發過來.已經不知道原文到底是出自哪裡了.  Java中有兩種實現多執行緒的方式。一是直接繼承Thread類,二是實現Runnable介面。那麼這兩種實現多執行緒的方式在應用上有什麼區別呢?       

java--執行建立的兩種方式ThreadRunnable介面

(一)繼承Thread類建立多執行緒----單執行緒下面的程式碼是一個死迴圈,但是不會執行main裡面的迴圈語句,而是run()裡面的語句,這是因為該程式是一個單執行緒程式,當呼叫MyThread類的run()方法時,遇到死迴圈,迴圈一直進行。因此,MyThread類的列印

javaSE (三十五執行 執行實現方法區別、同步程式碼塊方法執行安全

主要還是熟悉api,熟悉方法,簡單,需要多實踐 1、 多執行緒實現方法和區別: 多執行緒實現的兩種方法: 1)類繼承Thread類或實現Runnable介面,重寫run()方法 2)建立Thread的子類物件(需要開幾個執行緒就建立幾個物件,可建立匿名內部類) 3)子類

Java執行的實現程序與執行的概念、Java繼承Thread類實現執行、Java實現Runnable介面實現執行ThreadRunnable區別、實現Callable介面實現執行

1 程序與執行緒 1.1 程序與執行緒的概念 什麼是程序?   程序: 作業系統中一個程式的執行週期。(比如我們想要在電腦上登入QQ,從雙擊qq按鈕---->關閉qq這個過程就是一個程序)   多程序: 同一時刻跑多個程式。   在DOS(磁碟作業系統時

HashMap原始碼解析、jdk78之後的區別、相關問題分析執行擴容帶來的死迴圈

# 一、概覽 ```java HashMap map = new HashMap(); ``` 這個語句執行起來,在 jdk1.8 之前,會建立一個長度是 16 的 `Entry[]` 陣列,叫 `table`,用來儲存鍵值對。 在 jdk 1.8 後,不在這裡建立陣列了,而是在第一次 `pu

老男孩14期自動化運維day9隨筆作業執行批量管理主機

通過多執行緒實現基於paramiko的ssh,sftp的批量管理主機功能 需求: 1.主機分組 2.登入後顯示主機分組,選擇分組後檢視主機列表 3.可批量執行命令、傳送檔案,結果實時返回 4.主機使用者名稱密碼可以不同 只能執行paramiko.exec_command能執行的指令,

老男孩14期自動化運維day9隨筆作業執行批量管理主機

執行緒與程序 1.執行緒: os呼叫CPU進行運算的最小單位,被包含在程序中(就是一堆指令) 小知識點 運算速度比較:CPU>RAM>>磁碟 CPU 稍大於RAM(記憶體),RAM遠大於磁碟 每一個程式的記憶體都是獨立的,不能互相訪問 單核CPU只

老男孩14期自動化運維day9隨筆作業執行批量管理主機

1.paramiko 通過python實現模擬ssh批量登入 在linux系統上 ssh本身也可以用來傳檔案,例如:使用 scp -r /opt/test [email protected]_host:/opt 命令也可以執行傳輸檔案到遠端主機。 (小知識點:Linux中 l.可以

iOS應用開發基礎基礎知識資料儲存執行

本文可能涉及很多零碎的知識點,其中包括iOS應用開發的相關基礎知識。以後會針對每個條目在進行深入研究,這裡只是先做一個相關知識的概述總結。 iOS的資料儲存 大多數iOS程式其功能總結為:提供一套介面,幫助使用者管理特定資料。在這個過程中,不同物件各司其

Java物件鎖類鎖全面解析執行synchronized關鍵字

最近工作有用到一些多執行緒的東西,之前吧,有用到synchronized同步塊,不過是別人怎麼用就跟著用,並沒有搞清楚鎖的概念。最近也是遇到一些問題,不搞清楚鎖的概念,很容易碰壁,甚至有些時候自己連用沒用對都不知道。 今天把一些疑惑都解開了,寫篇文章分享給大家

VS2010/MFC入門程式設計十七執行的建立,包括工作執行使用者介面執行

1.MFC多執行緒簡介 MFC對多執行緒進行了一層簡單的封裝,在Visual C++中每個執行緒都是從CWinThread類繼承而來的。每一個應用程式的執行都有一個主執行緒,這個主執行緒也是從CWinThread類繼承而來的。可以利用CWinThread物件建立應用程式執行的其它執行緒。 MFC用CW

C#高效能大容量SOCKET併發:超時Socket斷開守護執行心跳包

守護執行緒 在服務端版Socket程式設計需要處理長時間沒有傳送資料的Socket,需要在超時多長時間後斷開連線,我們需要獨立一個執行緒(DaemonThread)來輪詢,在執行斷開時,需要把Socket物件鎖定,並呼叫CloseClientSocket來斷開連線,具體

群聊實現tcp執行

服務端程式碼 package com.cyj.tcp.chat2; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import ja

python爬蟲:爬取貓眼電影分數的處理執行

爬取用的庫是requests和beautifulsoup,程式碼編寫不難,主要是個別的細節處理需要注意 1、電影得分的處理 右鍵審查元素,我們看到分數的整數部分和小數部分是分開的,在beautifulsoup中,我們可以用(.strings或者.stripped_stri

WPF利用Interactive Data Display實現示波器C#執行WPF執行

2018.8.7(已實現) 首先,今天還沒有實現示波器,專案中需要這個功能,在探索中有了一點進展,先記錄下來。 實現的chart控制元件,能夠相應滑輪、滑鼠拖動、放大縮小,很適合作為示波器的背景。 關於Interactive Data Display的引用,可以考慮