<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>



    聯(lián)系博主          博客地圖
               
           感覺這個講的不錯,記錄一下,呵呵。
           進(jìn)程就是在某種程度上相互隔離的、獨立運行的程序。線程化是允許多個活動共存于一個進(jìn)程中的工具。大多數(shù)現(xiàn)代的操作系統(tǒng)都支持線程,而且線程的概念以各種形式已存在了好多年。Java 是第一個在語言本身中顯式地包含線程的主流編程語言,它沒有把線程化看作是底層操作系統(tǒng)的工具。
    有時候,線程也稱作輕量級進(jìn)程。就象進(jìn)程一樣,線程在程序中是獨立的、并發(fā)的執(zhí)行路徑,每個線程有它自己的堆棧、自己的程序計數(shù)器和自己的局部變量。但是,與分隔的進(jìn)程相比,進(jìn)程中的線程之間的隔離程度要小。它們共享內(nèi)存、文件句柄和其它每個進(jìn)程應(yīng)有的狀態(tài)。
    進(jìn)程可以支持多個線程,它們看似同時執(zhí)行,但互相之間并不同步。一個進(jìn)程中的多個線程共享相同的內(nèi)存地址空間,這就意味著它們可以訪問相同的變量和對象,而且它們從同一堆中分配對象。
    盡管這讓線程之間共享信息變得更容易,但您必須小心,確保它們不會妨礙同一進(jìn)程里的其它線程。
    每個 Java 程序都至少有一個線程 — 主線程。當(dāng)一個 Java 程序啟動時,JVM 會創(chuàng)建主線程,并在該線程中調(diào)用程序的 main() 方法。
    JVM 還創(chuàng)建了其它線程,您通常都看不到它們 — 例如,與垃圾收集、對象終止和其它 JVM 內(nèi)務(wù)處理任務(wù)相關(guān)的線程。其它工具也創(chuàng)建線程,如 AWT(抽象窗口工具箱(Abstract Windowing Toolkit))或 Swing UI 工具箱、servlet 容器、應(yīng)用程序服務(wù)器和 RMI(遠(yuǎn)程方法調(diào)用(Remote MethodInvocation))。
    多余的廢話就不寫那么多了,現(xiàn)在開始介紹一些實質(zhì)性的東西.
    為了確??梢栽诰€程之間以受控方式共享數(shù)據(jù),JAVA語言提供了兩個關(guān)鍵字是很重要的,他們就是:synchronized 和 volatile,所以在學(xué)習(xí)之前,這兩個鍵字的用法一定要搞清楚.
    Synchronized 有兩個重要含義:它確保了一次只有一個線程可以執(zhí)行代碼的受保護(hù)部分(互斥,mutual exclusion 或者說 mutex),而且它確保了一個線程更改的數(shù)據(jù)對于其它線程是可見的(更改的可見性)。
    如果沒有同步,數(shù)據(jù)很容易就處于不一致狀態(tài)。例如,如果一個線程正在更新兩個相關(guān)值(比如,粒子的位置和速率),而另一個線程正在讀取這兩個值,有可能在第一個線程只寫了一個值,還沒有寫另一個值的時候,調(diào)度第二個線程運行,這樣它就會看到一個舊值和一個新值。同步讓我們可以定義必須原子地運行的代碼塊,這樣對于其他線程而言,它們要么都執(zhí)行,要么都不執(zhí)行。
    Volatile 比同步更簡單,只適合于控制對基本變量(整數(shù)、布爾變量等)的單個實例的訪問。當(dāng)一個變量被聲明成 volatile,任何對該變量的寫操作都會繞過高速緩存,直接寫入主內(nèi)存,而任何對該變量的讀取也都繞過高速緩存,直接取自主內(nèi)存。這表示所有線程在任何時候看到的 volatile 變量值都相同。這兩個關(guān)鍵字的具體用法,我會在下一篇文章里面提到.
    再介紹一個概念,java鎖. 每個 Java 對象都有一個相關(guān)的鎖。同一時間只能有一個線程持有 Java 鎖。當(dāng)線程進(jìn)入synchronized 代碼塊時,線程會阻塞并等待,直到鎖可用,當(dāng)它可用時,就會獲得這個鎖,然后執(zhí)行代碼塊。當(dāng)控制退出受保護(hù)的代碼塊時,即到達(dá)了代碼塊末尾或者拋出了沒有在 synchronized 塊中捕獲的異常時,它就會釋放該鎖。
    好了,下面討論一下如何建立線程,有關(guān)線程的生命,
    在 Java 程序中創(chuàng)建線程有幾種方法。每個 Java 程序至少包含一個線程:主線程。其它線程都是通過 Thread 構(gòu)造器或?qū)嵗^承類 Thread 的類來創(chuàng)建的。在一個線程對新線程的 Thread 對象調(diào)用 start() 方法之前,這個新線程并沒有真正開始執(zhí)行。
    Thread 對象在其線程真正啟動之前就已經(jīng)存在了,而且其線程退出之后仍然存在。這可以讓您控制或獲取關(guān)于已創(chuàng)建的線程的信息,即使線程還沒有啟動或已經(jīng)完成了。
    通常在構(gòu)造器中通過 start() 啟動線程并不是好主意。這樣做,會把部分構(gòu)造的對象暴露給新的線程。如果對象擁有一個線程,那么它應(yīng)該提供一個啟動該線程的 start() 或 init() 方法,而不是從構(gòu)造器中啟動它。
    線程會以以下三種方式之一結(jié)束:
    · 線程到達(dá)其 run() 方法的末尾。
    · 線程拋出一個未捕獲到的 Exception 或 Error。
    · 另一個線程調(diào)用一個棄用的 stop() 方法。棄用是指這些方法仍然存在,但是您不應(yīng)該在新代碼中使用它們,并且應(yīng)該盡量從現(xiàn)有代碼中除去它們。
    當(dāng) Java 程序中的所有線程都完成時,程序就退出了。
    Thread API 包含了等待另一個線程完成的方法:join() 方法。當(dāng)調(diào)用 Thread.join() 時,調(diào)用線程將阻塞,直到目標(biāo)線程完成為止。
    Thread.join() 通常由使用線程的程序使用,以將大問題劃分成許多小問題,每個小問題分配一個線程。本章結(jié)尾處的示例創(chuàng)建了十個線程,啟動它們,然后使用 Thread.join() 等待它們?nèi)客瓿伞?br>Thread API 包含了等待另一個線程完成的方法:join() 方法。當(dāng)調(diào)用 Thread.join() 時,調(diào)用線程將阻塞,直到目標(biāo)線程完成為止。Thread.join() 通常由使用線程的程序使用,以將大問題劃分成許多小問題,每個小問題分配一個線程。我會在后面附上示例代碼,一個程序創(chuàng)建了十個線程,啟動它們,然后使用 Thread.join() 等待它們?nèi)客瓿伞?br>線程的調(diào)度是具有不確定性的,下面這個實例代碼就能說明這一點.
    public class TwoThreads {
    public static class Thread1 extends Thread {
    public void run() {
    System.out.println("A");
    System.out.println("B");
    }
    }
    public static class Thread2 extends Thread {
    public void run() {
    System.out.println("1");
    System.out.println("2");
    }
    }
    public static void main(String[] args) {
    new Thread1().start();
    new Thread2().start();
    }
    }
    誰能知道會打印出什么內(nèi)容呢?誰也不知道,因為沒有人知道執(zhí)行的順序,可能是一下的結(jié)果:
    · 1 2 A B
    · 1 A 2 B
    · 1 A B 2
    · A 1 2 B
    · A 1 B 2
    · A B 1 2
    不僅不同機器之間的結(jié)果可能不同,而且在同一機器上多次運行同一程序也可能生成不同結(jié)果。永遠(yuǎn)不要假設(shè)一個線程會在另一個線程之前執(zhí)行某些操作,除非您已經(jīng)使用了同步以強制一個特定的執(zhí)行順序。
    Thread API 包含了一個 sleep() 方法,它將使當(dāng)前線程進(jìn)入等待狀態(tài),直到過了一段指定時間,或者直到另一個線程對當(dāng)前線程的 Thread 對象調(diào)用了 Thread.interrupt(),從而中斷了線程。當(dāng)過了指定時間后,線程又將變成可運行的,并且回到調(diào)度程序的可運行線程隊列中。
    如果線程是由對 Thread.interrupt() 的調(diào)用而中斷的,那么休眠的線程會拋出異常InterruptedException,這樣線程就知道它是由中斷喚醒的,就不必查看計時器是否過期。
    Thread.yield() 方法就象 Thread.sleep() 一樣,但它并不引起休眠,而只是暫停當(dāng)前線程片刻,這樣其它線程就可以運行了。在大多數(shù)實現(xiàn)中,當(dāng)較高優(yōu)先級的線程調(diào)用 Thread.yield() 時,較低優(yōu)先級的線程就不會運行。
    我們提到過當(dāng) Java 程序的所有線程都完成時,該程序就退出,但這并不完全正確。隱藏的系統(tǒng)線程,如垃圾收集線程和由 JVM 創(chuàng)建的其它線程會怎么樣?我們沒有辦法停止這些線程。如果那些線程正在運行,那么 Java 程序怎么退出呢?
    這些系統(tǒng)線程稱作守護(hù)程序線程。Java 程序?qū)嶋H上是在它的所有非守護(hù)程序線程完成后退出的。
    任何線程都可以變成守護(hù)程序線程。可以通過調(diào)用 Thread.setDaemon() 方法來指明某個線程是守護(hù)程序線程。您也許想要使用守護(hù)程序線程作為在程序中創(chuàng)建的后臺線程,如計時器線程或其它延遲的事件線程,只有當(dāng)其它非守護(hù)程序線程正在運行時,這些線程才有用。
    在這個示例中,TenThreads 顯示了一個創(chuàng)建了十個線程的程序,每個線程都執(zhí)行一部分工作。該程序等待所有線程全部完成,然后收集結(jié)果。
    /**
    * Creates ten threads to search for the maximum value of a large matrix.
    * Each thread searches one portion of the matrix.
    */
    public class TenThreads {
    private static class WorkerThread extends Thread {
    int max = Integer.MIN_VALUE;
    int[] ourArray;
    public WorkerThread(int[] ourArray) {
    this.ourArray = ourArray;
    }
    // Find the maximum value in our particular piece of the array
    public void run() {
    for (int i = 0; i < ourArray.length; i++)
    max = Math.max(max, ourArray[i]);
    }
    public int getMax() {
    return max;
    }
    }
    public static void main(String[] args) {
    WorkerThread[] threads = new WorkerThread[10];
    int[][] bigMatrix = getBigHairyMatrix();
    int max = Integer.MIN_VALUE;
    // Give each thread a slice of the matrix to work with
    for (int i=0; i < 10; i++) {
    threads[i] = new WorkerThread(bigMatrix[i]);
    threads[i].start();
    }
    // Wait for each thread to finish
    try {
    for (int i=0; i < 10; i++) {
    threads[i].join();
    max = Math.max(max, threads[i].getMax());
    }
    }
    catch (InterruptedException e) {
    // fall through
    }
    System.out.println("Maximum value was " + max);
    }
    static   int[][]   getBigHairyMatrix()  
              {  
                int[][]   matrix=new   int[10][10];  
                for(int   i=0;i<10;i++)  
                    for(int   j=0;j<10;j++)  
                        {  
                          matrix[i][j]=(int)(Math.random()*1000);            
                        }  
                  return   matrix;          
                }  

    }
    總結(jié)幾句: 線程是通過實例化 Thread 對象或?qū)嵗^承 Thread 的對象來創(chuàng)建的,但在對新的 Thread 對象調(diào)用 start() 方法之前,這個線程并沒有開始執(zhí)行。當(dāng)線程運行到其 run() 方法的末尾或拋出未經(jīng)處理的異常時,它們就結(jié)束了。
    sleep() 方法可以用于等待一段特定時間;而 join() 方法可能用于等到另一個線程完成。
    (未完……………………………)

        核心: 勇敢進(jìn)取年輕的心

     


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    Copyright © 怎么羨慕天空的飛鳥

    主站蜘蛛池模板: 无码av免费网站| 亚洲国产成人AV网站| 久久亚洲私人国产精品| 亚洲熟妇自偷自拍另欧美| 美女黄频视频大全免费的| 精品国产污污免费网站| 免费可以在线看A∨网站| 免费少妇a级毛片人成网| 91天堂素人精品系列全集亚洲| 亚洲人成无码网站在线观看 | 免费人妻无码不卡中文字幕系| 免费人成网站在线观看10分钟| 亚洲福利中文字幕在线网址| 久久精品亚洲综合专区| 国产一区二区三区亚洲综合| 亚洲视频免费播放| 亚洲福利一区二区| 在线a毛片免费视频观看| 亚洲国产综合91精品麻豆| 又硬又粗又长又爽免费看 | 97性无码区免费| 国产偷v国产偷v亚洲高清| 亚洲a∨无码精品色午夜| 在免费jizzjizz在线播| 国产精品亚洲mnbav网站 | 国产日产亚洲系列| 国内精品一级毛片免费看| 亚洲午夜日韩高清一区| 亚洲欧美日韩久久精品| 久久国产高潮流白浆免费观看| 日韩精品电影一区亚洲| 亚洲精品无码国产片| 免费福利网站在线观看| 久久狠狠高潮亚洲精品| 久久精品无码专区免费| 亚洲av成人一区二区三区在线观看| 亚洲最大天堂无码精品区| 四虎永久在线精品免费观看视频| 亚洲精品自产拍在线观看动漫| 国产VA免费精品高清在线| 免费在线观看毛片|