<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 © 怎么羨慕天空的飛鳥

    主站蜘蛛池模板: 亚洲国产精品专区在线观看| 国产精品亚洲小说专区| 国产乱辈通伦影片在线播放亚洲| 国产成人福利免费视频| a色毛片免费视频| 青青草97国产精品免费观看| 亚洲色偷偷综合亚洲av78| 91亚洲国产成人精品下载| 亚洲AV一宅男色影视| 国产国拍精品亚洲AV片| 国产免费一区二区三区VR| 大地资源二在线观看免费高清| 一级毛片在线观看免费| 一级特黄aaa大片免费看| 美女被免费网站在线视频免费| 亚洲人片在线观看天堂无码| 国产成人精品日本亚洲11| 亚洲欧洲日产韩国在线| 亚洲日本在线观看| 亚洲成色WWW久久网站| 亚洲熟妇丰满多毛XXXX| 国产亚洲精品AA片在线观看不加载 | 最新亚洲人成网站在线观看| 丁香婷婷亚洲六月综合色| 色在线亚洲视频www| 国产亚洲sss在线播放| 亚洲中文字幕无码中文| 亚洲午夜精品一区二区麻豆| 亚洲熟妇av一区二区三区下载| 久久亚洲精精品中文字幕| 久久亚洲精品无码aⅴ大香| 亚洲成人在线网站| 亚洲精品视频专区| 亚洲激情黄色小说| 亚洲人成77777在线播放网站不卡| 亚洲一卡二卡三卡四卡无卡麻豆| 亚洲av产在线精品亚洲第一站| youjizz亚洲| 亚洲av永久无码一区二区三区| 亚洲av无码专区国产不乱码| 在线观看亚洲专区|