1. 程式人生 > >Java5 多執行緒(一)入門篇

Java5 多執行緒(一)入門篇

首先回顧一下JDK1.5之前的執行緒相關的知識:1 執行緒的入門.        什麼是執行緒,執行緒就是程式執行的線索,Java是面向物件的語言什麼類來表示這樣一個東西呢?Thread.通過start()方法啟動它,執行緒所要執行的任務放在run()方法裡面,下面可以看一下run()方法裡面的原始碼
建立執行緒的兩種傳統方式(注: Runnable類並不是一個執行緒,它只是執行緒一個執行單元):
開啟Thread的構造方法,
然後可以跟進看到init()方法具體的實現.其中有一行程式碼就是對target(Runnable型別)的賦值,因為執行緒所執行的任務都在run()方法裡面,那麼在run()方法裡面,target就不為null,然後就呼叫了Runnale的run()方法.因為我們重寫了Runnable的run()方法,那麼最終執行的就是我們所覆寫的run()方法.具體程式碼如下:

      如果我們同時實現了Thread的run()方法又同時覆蓋了Runnable的run()方法.那麼到底會執行哪個的run()方法呢?根據Java的多型,肯定執行的是Thread的run()方法.因為我們覆寫了Thread的run()方法,那麼所執行的就是我們run()方法,而不是
2 傳統的定時器:        定時器通過Timer這個類來描述,通過schedule()方法來排程,定時執行的任務通過TimerTask來定義.下面來實現一個簡單的定時器,功能如下,每隔2秒執行一次,之後隔4秒執行一次,然後又隔2秒,就這樣輪循下去.具體用法可以檢視API裡面有詳細介紹.
  1. publicstatic
    void main(String[] args) {  
  2.     new Timer().schedule(new MyTimerTask(), 2000);  
  3.     try {  
  4.         while (true) {  
  5.         System.out.println(new Date().getSeconds());  
  6.         Thread.sleep(1000);  
  7.     }  
  8. catch (InterruptedException e) {  
  9.     e.printStackTrace();  
  10.         }  
  11.     }  
  12.     }  
  13. class MyTimerTask 
    extends TimerTask {  
  14.     staticint count = 0;  
  15.     @Override
  16.     publicvoid run() {  
  17.         count = (count + 1) % 2;//count=0或1
  18.         System.out.println("boming");  
  19.         Timer timer = new Timer();  
  20.         timer.schedule(new MyTimerTask(), 2000 + (2000) * count);  
  21.     }  
3 執行緒之間的互斥和同步通訊當兩個執行緒去同時操作一個字串,那麼可能會出現執行緒安全問題.這樣的情況可以用銀行轉帳來解釋.下面的程式碼就會出現問題,
  1. publicstaticvoid main(String[] args) {  
  2. final Outputer outputer = new Outputer();  
  3. new Thread() {  
  4. @Override
  5. publicvoid run() {  
  6. while (true) {  
  7. try {  
  8. Thread.sleep(100);  
  9. catch (InterruptedException e) {  
  10. e.printStackTrace();  
  11. }  
  12. outputer.print("zhangsan");  
  13. }  
  14. }  
  15. }.start();  
  16. new Thread() {  
  17. @Override
  18. publicvoid run() {  
  19. while (true) {  
  20. try {  
  21. Thread.sleep(100);  
  22. catch (InterruptedException e) {  
  23. e.printStackTrace();  
  24. }  
  25. outputer.print("zhangxiaoxiang");  
  26. }  
  27. }  
  28. }.start();  
  29. }  
  30. }  
  31. class Outputer {  
  32. publicvoid print(String name) {  
  33. for (int i = 0; i < name.length(); i++) {  
  34. System.out.print(name.charAt(i));  
  35. }  
  36. System.out.println();// 列印完字串換行
  37. }  
  38. }  

我們使用兩個執行緒去呼叫print(String name)方法,當第一個方法還沒有執行完畢,第二個方法來執行,那麼打印出來的name就會出現為問題.如下圖所示,
現在我們要實現的是,只有當第一個執行緒執行完畢後,第二個執行緒才能執行print(String name)方法,這就必須互斥或者說同步.我們知道實現同步可以使用同步程式碼塊或者同步方法,想到同步(Synchronized)那麼自然而然就想到同步監視器.這是兩個很重要的概念.現在我們來改造上面Outputer的print(String name)方法.
  1. publicvoid print(String name) {  
  2. //synchronized()裡面的引數就是同步監視器
  3. //然而這裡使用name作為同步監視器是不行的,
  4. //因為要實現原子性(互斥)必須要使用同一個監視器物件
  5. //當第一個執行緒來執行該程式碼塊,name物件是一個String物件
  6. //當第二個執行緒來執行,name物件又是另一個String物件,
  7. //這樣就不能實現同步
  8. synchronized (name) {  
  9. for (int i = 0; i < name.length(); i++) {  
  10. System.out.print(name.charAt(i));  
  11. }  
  12. System.out.println();// 列印完字串換行
  13. }  
  14. }   
執行結果如下所示:
我們可以通過this關鍵字作為同步監視器,因為從上面定義兩個執行緒的程式碼來看,我們只new了一次Outputer物件,所以this代表同一個物件.現在來通過同步方法來實現同步,
  1. //同步方法也同樣也有同步監視器,它是this
  2. publicsynchronizedvoid print2(String name) {  
  3.     for (int i = 0; i < name.length(); i++) {  
  4.         System.out.print(name.charAt(i));  
  5.     }  
  6.     System.out.println();// 列印完字串換行
  7. }  
把第二個執行緒改成使用print2(String name)方法.這樣的話就需要print2和print這兩個方法互斥.這個怎麼理解呢?上面我們是對print()這個一個方法進行互斥,現在呢?需要對兩個方法進行互斥.我們可以這樣比喻(對一個方法進行互斥):假設一個茅坑(print(String name)),上面有一把鎖(this物件),現在一個人(Thread)來上廁所,它把鑰匙放進了口袋,第二個人(Thread2)來上廁所,因為沒有鑰匙,必須要等第一個人出來,把鑰匙放上去,第二個人才能拿著鑰匙進去.這是對一個方法進行同步,(對兩個方法或者更多進行同步)),現在有多個茅坑(print(String name),print2(String name)),只有一個鑰匙(同步監視器),那麼當一個人(Thread)進去後,拿了那僅有的一個鑰匙,就算其他人(Thread)想進入的沒有人佔的茅坑也不行,因為沒有鑰匙.        這樣的話,列印name的時候就不會出現問題.現在還有一種情況:
  1. //靜態的同步方法同樣也有同步監視器,它是class
  2. publicstaticsynchronizedvoid print3(String name) {  
  3. for (int i = 0; i < name.length(); i++) {  
  4. System.out.print(name.charAt(i));  
  5. }  
  6. System.out.println();// 列印完字串換行
  7. }   
這樣的話要想互斥就必須把同步監視器改成Outputer.class了,在記憶體中只有一份.執行緒之間的同步通訊通過一道面試提來解釋.子執行緒迴圈10次,接著主執行緒迴圈100,接著又回到子執行緒迴圈10次,接著再回到主執行緒又迴圈100,如此迴圈50次,請寫出程式。
  1. //靜態的同步方法同樣也有同步監視器,它是class
  2. publicstaticsynchronizedvoid print3(String name) {  
  3. for (int i = 0; i < name.length(); i++) {  
  4. System.out.print(name.charAt(i));  
  5. }  
  6. System.out.println();// 列印完字串換行
  7. }   
  8. 這樣的話要想互斥就必須把同步監視器改成Outputer.class了,在記憶體中只有一份.  
  9. 執行緒之間的同步通訊  
  10. 通過一道面試提來解釋.  
  11. 子執行緒迴圈10次,接著主執行緒迴圈100,接著又回到子執行緒迴圈10次,接著再回到主執行緒又迴圈100,如此迴圈50次,請寫出程式。  
  12. publicstaticvoid main(String[] args) {  
  13. new Thread(new Runnable() {  
  14. @Override
  15. 相關推薦

    Java5 執行入門

    首先回顧一下JDK1.5之前的執行緒相關的知識:1 執行緒的入門.        什麼是執行緒,執行緒就是程式執行的線索,Java是面向物件的語言什麼類來表示這樣一個東西呢?Thread.通過start()方法啟動它,執行緒所要執行的任務放在run()方法裡面,下面可以看一下

    Java執行基礎

    1.關於執行緒與程序的區別:執行緒指程序中的一個執行場景,也就是執行流程,同一個程序中的執行緒共享其程序中的記憶體和資源(共享的記憶體是堆記憶體和方法區記憶體,棧記憶體不共享,每個執行緒有自己的,一個執行緒一個棧。);每個程序是一個應用程式,都有獨立的記憶體空間。多執行緒的使用是為了提高程式

    Java 執行—— 概念的引入

      併發和並行      程序和執行緒      如何建立多執行緒      第一種方法:繼承 Thread 類      第二種方法:實現 Runnable 介面      第三種方法:使用匿名內部類建立執行緒      正文      回到頂部      併發和並行      並行:指兩個或多個

    深入理解Java執行

    關於java多執行緒的概念以及基本用法:java多執行緒基礎 1,停止執行緒 停止執行緒意味著線上程執行完之前停止正在做的操作,即立刻放棄當前的操作,這並不容易。停止執行緒可以用Thread.stop()方法,但是這個方法不安全,所以不建議使用,還有一個方法就是Thre

    Java執行 什麼是執行

    宣告:本系列大多是翻譯自https://www.javatpoint.com,加上自己的增刪改,盡力寫的系統而通俗易懂,後文不再重複宣告。 java的多執行緒是一個同時執行多個執行緒的過程。 執行緒是一個輕量級的子程序,是最小的處理單元。多執行緒和多程序都用於實現多工處理。 但是,我們使用多執

    java執行:執行的五種基本狀態以及生命週期

    1、Java執行緒具有五中基本狀態: 新建狀態(New):當執行緒物件對建立後,即進入了新建狀態,如:Thread thread1 = new MyThread(); 就緒狀態(Runnable):當呼叫執行緒物件的start()方法[ 如:thread1 .start(); ],執行緒

    11 非同步執行

    任何的非同步多執行緒,都是和委託相關,沒有委託,啥也沒有。 BeginInvoke在 C#裡面,就是啟動一個執行緒完成任務。 用設定斷點的方法來除錯的非同步多執行緒,是行不通的,只有多寫一些日誌或者輸出文字資訊到控制檯程式上。 如果要想看到控制檯程式一樣的介面輸出結果,

    淺解執行

    多執行緒的相關概念 1.程序:是作業系統結構的基礎;是一個正在執行的程式;計算機中正在執行的程式例項;可以分配給處理器並由處理器執行的一個實體;由單一順序的執行顯示,一個當前狀態和一組相關的系統資源所描述的活動單元。 2.執行緒:執行緒是程式中一個單一的順序控

    結合生活,剖析《生產者消費者模型》-java執行

      部落格園的園友們好,看部落格園上各位大佬的文章,已陪伴了我程式設計師職業的三年, 如今自己同樣希望能把自己從小白到菜鳥的成長過程分享給大家。不定期更新!!! 首先我本人智商不高,理解問題十分吃力,完全不屬於天才的行列,因此學習每一個知識 都喜歡刨根問底,結合生活,徹徹底底理解知識的本質! 進入正題,這篇文

    Java執行執行基礎及建立

    (一)、執行緒的生命週期 新建狀態: 使用 new 關鍵字和 Thread 類或其子類建立一個執行緒物件後,該執行緒物件就處於新建狀態。它保持這個狀態直到程式 start() 這個執行緒。 就緒狀態: 當執行緒物件呼叫了start()方法之後,該執行緒就進入就緒

    執行ThreadLocal 執行內資料共享

    每個執行緒單獨一份資料ThreadLocal   import java.util.Random; public class D { // public static ThreadLocal<Integer> map=new ThreadLocal<Intege

    執行基礎部分

    多執行緒基礎 執行緒釋義 計算機採用多工設計,每個任務對應一個程序。例如執行 中的qq.exe對應作業系統中的一個程序。程序的特點是: 程序是系統執行的基本單位 每個程序有自己獨立的記憶體空間、系統資源 每個程序的內部資料和狀態是完全獨立的。 一個程序,可以

    執行

    多執行緒是指的是這個程式(一個程序)執行時產生了不止一個執行緒。 並行與併發區別: 並行:多個cpu例項或者多臺機器同時執行一段處理邏輯,是真正的同時。 併發:通過cpu排程演算法,讓使用者看上去同時執行,實際上從cpu操作層面不是真正的同時。併發往往在場景中有公用的資源,那

    深入理解執行——Synchronized的實現原理

    synchronized,是Java中用於解決併發情況下資料同步訪問的一個很重要的關鍵字。當我們想要保證一個共享資源在同一時間只會被一個執行緒訪問到時,我們可以在程式碼中使用synchronized關鍵字對類或者物件加鎖。那麼,本文來介紹一下synchronized關鍵字的實

    瘋狂java講義:執行

    第十六章  多執行緒(一)     並行:在同一時刻,有多條指令在多個處理器上同時執行     併發:同一時刻只有一個指令被處理器執行,但多個程序指令快速輪換執行,使得巨集觀好像多個指令在同時執行     作業系統可以同時執行多個任務,每個任務就是程序;程序可以

    JAVA基礎22-執行執行的概念,執行狀態及其轉換】

    多執行緒 一.概念          1. 程序:程序是表示資源分配的的基本概念,又是排程執行的基本單位,是系統中的併發執行的單位。           2. 執行緒:單個程序中執行中

    程序與執行--基本概念(轉)

    程序(英語:Process,中國大陸譯作程序,臺灣譯作行程) 是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,是系統進行資源分配和排程的一個獨立單位。程式是一組指令的有序集合,它本身沒有任何執行的含義,只是一個靜態實體。程序是程式在某個資料集上的執行,是一個動態實體(程序本身不會執行,是執行緒的容器

    理解執行

    引入併發概念 單道作業系統 其實在單道系統時期,是沒有併發的,cpu更是沒有多核。程式設計師輸入資料,計算機處理,計算機輸出結果,每次一個程式執行完才能執行其他程式。但不久聰明的程式設計師們發現這樣極大的浪費計算機資源。比如,在執行一個算術問題時候,程式設計師輸入資料是很慢的(sca

    Java執行 —— 執行的狀態詳解

    一、多執行緒概述  1、 程序 是一個正在執行的程式。是程式在計算機上的一次執行活動。 每一個程序執行都有一個執行順序。該順序是一個執行路徑,或者叫一個控制單元。 系統以程序為基本單位進行系統資源的排程和分配。程式要執行,系統就在記憶體中為該程式分配一塊獨立的記憶體空間,載入程式程式碼和資源進行執行。 程式

    java基礎的核心技術:執行

    1、程式、程序、執行緒的概念 2、java中多執行緒的建立和使用(重點) 2.1、繼承Thread類與實現Runnable介面 2.2、Thread類的主要方法 2.3、執行緒的排程與設定優先順序 3、執行緒的生命週期 4、執行緒的同步(重點) 5、執行緒的通訊  ---