青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

編寫高效的java線程安全類

2000 4 01

在語言級支持鎖定對象和線程間發信使編寫線程安全類變得簡單。本文使用簡單的編程示例來說明開發高效的線程安全類是多么有效而直觀。

Java 編程語言為編寫多線程應用程序提供強大的語言支持。但是,編寫有用的、沒有錯誤的多線程程序仍然比較困難。本文試圖概述幾種方法,程序員可用這幾種方法來創建高效的線程安全類。

并發性

只有當要解決的問題需要一定程度的并發性時,程序員才會從多線程應用程序中受益。例如,如果打印隊列應用程序僅支持一臺打印機和一臺客戶機,則不應該將它編寫為多線程的。一般說來,包含并發性的編碼問題通常都包含一些可以并發執行的操作,同時也包含一些不可并發執行的操作。例如,為多個客戶機和一個打印機提供服務的打印隊列可以支持對打印的并發請求,但向打印機的輸出必須是串行形式的。多線程實現還可以改善交互式應用程序的響應時間。

 

 

Synchronized 關鍵字

雖然多線程應用程序中的大多數操作都可以并行進行,但也有某些操作(如更新全局標志或處理共享文件)不能并行進行。在這些情況下,必須獲得一個鎖來防止其他線程在執行此操作的線程完成之前訪問同一個方法。在 Java 程序中,這個鎖是通過 synchronized 關鍵字提供的。清單 1 說明了它的用法。


清單 1. 使用 synchronized 關鍵字來獲取鎖

public class MaxScore {
    int max;
    public MaxScore() {
        max = 0;
    }
    public synchronized void currentScore(int s) {
        if(s> max) {
            max = s;
        }
    }
    public int max() {
        return max;
    }
}

 

這里,兩個線程不能同時調用 currentScore() 方法;當一個線程工作時,另一個線程必須阻塞。但是,可以有任意數量的線程同時通過 max() 方法訪問最大值,因為 max() 不是同步方法,因此它與鎖定無關。

試考慮在 MaxScore 類中添加另一個方法的影響,該方法的實現如清單 2 所示。


清單 2. 添加另一個方法

   public synchronized void reset() {
        max = 0;
    }

 

這個方法(當被訪問時)不僅將阻塞 reset() 方法的其他調用,而且也將阻塞 MaxScore 類的同一個實例中的 currentScore() 方法,因為這兩個方法都訪問同一個鎖。如果兩個方法必須不彼此阻塞,則程序員必須在更低的級別使用同步。清單 3 是另一種情況,其中兩個同步的方法可能需要彼此獨立。


清單 3. 兩個獨立的同步方法

import java.util.*;
public class Jury {
    Vector members;
    Vector alternates;
    public Jury() {
        members = new Vector(12, 1);
        alternates = new Vector(12, 1);
    }
    public synchronized void addMember(String name) {
        members.add(name);
    }
    public synchronized void addAlt(String name) {
        alternates.add(name);
    }
    public synchronized Vector all() {
        Vector retval = new Vector(members);
        retval.addAll(alternates);
        return retval;
    }
}

 

此處,兩個不同的線程可以將 members alternates 添加到 Jury 對象中。請記住, synchronized 關鍵字既可用于方法,更一般地,也可用于任何代碼塊。清單 4 中的兩段代碼是等效的。


清單 4. 等效的代碼

synchronized void f() {              void f() {      
    // 執行某些操作                                              synchronized(this) {
}                                                    // 執行某些操作
                                            }
                                     }  

 

所以,為了確保 addMember() addAlt() 方法不彼此阻塞,可按清單 5 所示重寫 Jury 類。


清單 5. 重寫后的 Jury

import java.util.*;
public class Jury {
    Vector members;
    Vector alternates;
    public Jury() {
        members = new Vector(12, 1);
        alternates = new Vector(12, 1);
    }
    public void addMember(String name) {
        synchronized(members) {
            members.add(name);
        }
    }
    public void addAlt(String name) {
        synchronized(alternates) {
            alternates.add(name);
        }
    }
    public Vector all() {
        Vector retval;
        synchronized(members) {
            retval = new Vector(members);
        }
        synchronized(alternates) {
            retval.addAll(alternates);
        }
        return retval;
    }
}

 

請注意,我們還必須修改 all() 方法,因為對 Jury 對象同步已沒有意義。在改寫后的版本中,addMember()addAlt() all() 方法只訪問與 members alternates 對象相關的鎖,因此鎖定 Jury 對象毫無用處。另請注意,all() 方法本來可以寫為清單 6 所示的形式。


清單 6. members alternates 用作同步的對象

   public Vector all() {
        synchronized(members) {
            synchronized(alternates) {
                Vector retval;
                retval = new Vector(members);
                retval.addAll(alternates);
            }
        }
        return retval;
    }

 

但是,因為我們早在需要之前就獲得 members alternates 的鎖,所以這效率不高。清單 5 中的改寫形式是一個較好的示例,因為它只在最短的時間內持有鎖,并且每次只獲得一個鎖。這樣就完全避免了當以后增加代碼時可能產生的潛在死鎖問題。

 

 

同步方法的分解

正如在前面看到的那樣,同步方法獲取對象的一個鎖。如果該方法由不同的線程頻繁調用,則此方法將成為瓶頸,因為它會對并行性造成限制,從而會對效率造成限制。這樣,作為一個一般的原則,應該盡可能地少用同步方法。盡管有這個原則,但有時一個方法可能需要完成需要鎖定一個對象幾項任務,同時還要完成相當耗時的其他任務。在這些情況下,可使用一個動態的鎖定-釋放-鎖定-釋放方法。例如,清單 7 和清單 8 顯示了可按這種方式變換的代碼。


清單 7. 最初的低效率代碼

public synchonized void doWork() {
         unsafe1();
    write_file();
    unsafe2();
}




清單 8. 重寫后效率較高的代碼

public void doWork() {
    synchonized(this) {
                 unsafe1();
    }
    write_file();
    synchonized(this) {
        unsafe2();
    }
}

 

清單 7 和清單 8 假定第一個和第三個方法需要對象被鎖定,而更耗時的 write_file() 方法不需要對象被鎖定。如您所見,重寫此方法以后,對此對象的鎖在第一個方法完成以后被釋放,然后在第三個方法需要時重新獲得。這樣,當 write_file() 方法執行時,等待此對象的鎖的任何其他方法仍然可以運行。將同步方法分解為這種混合代碼可以明顯改善性能。但是,您需要注意不要在這種代碼中引入邏輯錯誤。

 

 

嵌套類

內部類在 Java 程序中實現了一個令人關注的概念,它允許將整個類嵌套在另一個類中。嵌套類作為包含它的類的一個成員變量。如果定期被調用的的一個特定方法需要一個類,就可以構造一個嵌套類,此嵌套類的唯一任務就是定期調用所需的方法。這消除了對程序的其他部分的相依性,并使代碼進一步模塊化。清單 9,一個圖形時鐘的基礎,使用了內部類。


清單 9. 圖形時鐘示例

public class Clock {
    protected class Refresher extends Thread {
        int refreshTime;
        public Refresher(int x) {
            super("Refresher");
            refreshTime = x;
        }
        public void run() {
            while(true) {
                try {
                    sleep(refreshTime);
                }
                catch(Exception e) {}
                repaint();
            }
        }
    }
    public Clock() {
        Refresher r = new Refresher(1000);
        r.start();
    }
    private void repaint() {
        // 獲取時間的系統調用
        // 重繪時鐘指針
    }
}

 

清單 9 中的代碼示例不靠任何其他代碼來調用 repaint() 方法。這樣,將一個時鐘并入一個較大的用戶界面就相當簡單。

 

 

事件驅動處理

當應用程序需要對事件或條件(內部的和外部的)作出反映時,有兩種方法或用來設計系統。在第一種方法(稱為輪詢)中,系統定期確定這一狀態并據此作出反映。這種方法(雖然簡單)也效率不高,因為您始終無法預知何時需要調用它。

第二種方法(稱為事件驅動處理)效率較高,但實現起來也較為復雜。在事件驅動處理的情況下,需要一種發信機制來控制某一特定線程何時應該運行。在 Java 程序中,您可以使用 wait()notify() notifyAll() 方法向線程發送信號。這些方法允許線程在一個對象上阻塞,直到所需的條件得到滿足為止,然后再次開始運行。這種設計減少了 CPU 占用,因為線程在阻塞時不消耗執行時間,并且可在 notify() 方法被調用時立即喚醒。與輪詢相比,事件驅動方法可以提供更短的響應時間。

 

 

創建高效的線程安全類的步驟

編寫線程安全類的最簡單的方法是用 synchronized 聲明每個方法。雖然這種方案可以消除數據損壞,但它同時也會消除您預期從多線程獲得的任何收益。這樣,您就需要分析并確保在 synchronized 塊內部僅占用最少的執行時間。您必須格外關注訪問緩慢資源文件、目錄、網絡套接字和數據庫的方法,這些方法可能降低您的程序的效率。盡量將對這類資源的訪問放在一個單獨的線程中,最好在任何 synchronized 代碼之外。

一個線程安全類的示例 被設計為要處理的文件的中心儲存庫。它與使用 getWork() finishWork() WorkTable 類對接的一組線程一起工作。本例旨在讓您體驗一下全功能的線程安全類,該類使用了 helper 線程和混合同步。請注意繼續添加要處理的新文件的Refresher helper 線程的用法。本例沒有調整到最佳性能,很明顯有許多地方可以改寫以改善性能,比如將 Refresher 線程改為使用 wait()/notify() 方法事件驅動的,改寫 populateTable() 方法以減少列出磁盤上的文件(這是高成本的操作)所產生的影響。

 

 

小結

通過使用可用的全部語言支持,Java 程序中的多線程編程相當簡單。但是,使線程安全類具有較高的效率仍然比較困難。為了改善性能,您必須事先考慮并謹慎使用鎖定功能。

 

參考資料

 

關于作者

clip_image002

 

clip_image003

Neel V. Kumar 是一位具有八年面向對象編程經驗的軟件工程師,所用的語言為 C++ Java 編程語言。他出生在愛荷華州,目前住在加利福尼亞的 Menlo Park,剛剛涉足電信領域。他曾經為許多項目提供過咨詢服務,并樂意與別人分享他的知識。可以通過 neelvk@terway.com 與他聯系。

 

posted on 2009-08-25 22:38 肥仔 閱讀(716) 評論(0)  編輯 收藏 引用 所屬分類: Web-后臺

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久久欧美精品| 亚洲人成欧美中文字幕| 亚洲在线免费| 一区二区三区鲁丝不卡| 99亚洲视频| 亚洲午夜av在线| 亚洲欧美bt| 久久九九99视频| 欧美插天视频在线播放| 欧美另类高清视频在线| 国产噜噜噜噜噜久久久久久久久| 国产乱人伦精品一区二区 | 国产午夜一区二区三区| 狠狠爱综合网| 日韩亚洲欧美在线观看| 亚洲欧美日韩国产综合在线 | 日韩一区二区精品视频| 亚洲欧美一区二区视频| 久久久噜噜噜久久久| 欧美成人精品在线播放| 国产精品毛片a∨一区二区三区| 国内精品嫩模av私拍在线观看| 亚洲精品视频中文字幕| 久久精品在线| 亚洲毛片在线| 久久精品九九| 国产精品一国产精品k频道56| 在线观看欧美日韩国产| 亚洲欧美激情视频| 欧美国产一区二区三区激情无套| 夜夜嗨av一区二区三区中文字幕 | 欧美专区第一页| 欧美第一黄色网| 国产视频一区二区三区在线观看| 欧美一区二区精美| 亚洲免费电影在线观看| 久久爱www.| 亚洲精品极品| 先锋影音国产精品| 欧美精品在线网站| 伊人久久综合97精品| 性8sex亚洲区入口| 亚洲精品综合精品自拍| 玖玖综合伊人| 韩国在线视频一区| 欧美一区二区三区在线| 一区二区久久| 欧美日韩另类综合| 亚洲精品永久免费| 欧美大片在线观看一区| 久久国产精品亚洲77777| 国产精品久久一级| 亚洲免费视频网站| 亚洲精品中文在线| 欧美精品一区二| 日韩视频第一页| 欧美成年人视频网站欧美| 欧美在线日韩在线| 国产午夜精品理论片a级大结局 | 午夜精品久久久久久久99樱桃| 亚洲国产一区二区三区高清| 久久久久久久一区二区| 经典三级久久| 久久免费视频网| 久久久久国产精品一区二区| 国产伦精品一区| 久久国产精品久久久久久电车| 亚洲视频观看| 国产九色精品成人porny| 久久激情综合| 欧美在线免费观看| 亚洲黄色成人网| 欧美国产成人精品| 欧美连裤袜在线视频| 99在线|亚洲一区二区| 一区二区三区精密机械公司 | 一区二区三区四区精品| 国产精品高潮呻吟视频| 欧美一区二区在线观看| 欧美一区日韩一区| 亚洲黄色成人网| 中文国产亚洲喷潮| 国产一区二区三区免费在线观看| 女女同性精品视频| 欧美日韩999| 久久九九热免费视频| 久久免费精品日本久久中文字幕| 亚洲三级毛片| 亚洲影视在线| 香蕉av福利精品导航| 久久精品国产亚洲高清剧情介绍 | 中国成人在线视频| 亚洲中无吗在线| 亚洲国产精品成人一区二区 | 欧美日韩综合另类| 久久成人久久爱| 美女精品自拍一二三四| 亚洲视频精选在线| 久久久一二三| 亚洲综合不卡| 女生裸体视频一区二区三区| 亚洲午夜一区二区三区| 久久全国免费视频| 亚洲午夜女主播在线直播| 久久久久久穴| 亚洲天堂av高清| 国产精品99久久久久久有的能看| 一区二区三区在线免费播放| 一本久道久久久| 亚洲国产欧美久久| 亚洲男人av电影| 亚洲午夜激情| 欧美va亚洲va香蕉在线| 久久精品道一区二区三区| 欧美久久久久久久| 美女尤物久久精品| 国产亚洲精品综合一区91| 欧美伊人精品成人久久综合97| 欧美精品在线免费| 欧美mv日韩mv亚洲| 激情欧美一区| 亚洲专区在线| 亚洲欧美99| 欧美日韩午夜激情| 最近看过的日韩成人| 在线观看一区二区视频| 欧美亚洲一区二区在线| 亚洲欧美日韩在线不卡| 欧美日韩国产精品自在自线| 亚洲福利视频在线| 黄色精品免费| 久久九九热免费视频| 欧美在线日韩在线| 国产日韩精品在线播放| 亚洲视频高清| 新片速递亚洲合集欧美合集| 欧美日韩一区在线播放| 亚洲六月丁香色婷婷综合久久| 亚洲精品国产精品国产自| 麻豆免费精品视频| 欧美成人免费全部| 亚洲人久久久| 欧美日韩福利视频| 在线亚洲一区| 欧美专区在线| 美女视频黄免费的久久| 免费看亚洲片| 亚洲国产日韩欧美在线动漫| 欧美肥婆在线| 日韩视频一区二区在线观看| 欧美激情精品久久久久久大尺度 | 久久女同互慰一区二区三区| 欧美一区二区三区四区在线观看| 性18欧美另类| 国产精品综合久久久| 欧美在线一二三| 久久一区二区三区国产精品 | 国产亚洲欧美日韩在线一区| 久久精品毛片| 亚洲国产精品传媒在线观看| 日韩午夜在线视频| 欧美在线一级va免费观看| 久久综合电影| 亚洲精品国产精品乱码不99| 国产精品美女久久久| 久久av一区| 亚洲国产精品成人| 亚洲免费伊人电影在线观看av| 国内伊人久久久久久网站视频| 久久深夜福利| 中文在线资源观看网站视频免费不卡| 欧美亚洲免费| 日韩天堂在线观看| 国产毛片精品国产一区二区三区| 老鸭窝亚洲一区二区三区| 亚洲精品裸体| 久久在线免费| 亚洲永久在线| 最新国产成人av网站网址麻豆 | 久久久精品久久久久| 亚洲美女在线看| 国产日本亚洲高清| 欧美日韩一区二区国产| 久久久精品国产免费观看同学| 99国产成+人+综合+亚洲欧美| 久久久另类综合| 亚洲网在线观看| 亚洲人成毛片在线播放| 国产一区二区高清| 国产精品都在这里| 欧美电影免费观看大全| 性色av一区二区三区在线观看| 亚洲人精品午夜| 欧美成年人网| 久久久久久噜噜噜久久久精品 | 欧美黑人在线播放| 久久久久免费视频| 亚洲欧美色婷婷| 亚洲午夜精品国产| 亚洲免费黄色|