成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 線程相關(guān)類

Sanchi / 1919人閱讀

摘要:提供了線程安全的共享對(duì)象,在編寫(xiě)多線程代碼時(shí),可把不安全的整個(gè)變量封裝進(jìn),或者把該對(duì)象與線程相關(guān)的狀態(tài)使用保存并不能替代同步機(jī)制,兩者面向的問(wèn)題領(lǐng)域不同。

ThreadLocal類

使用ThreadLocal類可以簡(jiǎn)化多線程編程時(shí)的并發(fā)訪問(wèn),使用這個(gè)工具類可以很簡(jiǎn)捷地隔離多線程程序的競(jìng)爭(zhēng)資源。Java5之后,為ThreadLocal類增加了泛型支持,即ThreadLocal

ThreadLocal,是Thread Local Variable (線程局部變量) 的意思。功能就是為每一個(gè)使用該變量的線程都提供一個(gè)變量值的副本,使每一個(gè)線程都可以獨(dú)立的改變自己的副本,而不會(huì)與其他線程的副本沖突。從線程的角度看,就好像每一個(gè)線程都完全擁有該變量一樣

ThreadLocal類的三個(gè)public方法:

T get():返回此線程局部變量中當(dāng)前線程副本中的值

void remove():刪除此線程局部變量中當(dāng)前線程的值

void set(T value):設(shè)置此線程局部變量中當(dāng)前線程副本中的值

class Account
{
    /* 定義一個(gè)ThreadLocal類型的變量,該變量將是一個(gè)線程局部變量
    每個(gè)線程都會(huì)保留該變量的一個(gè)副本 */
    private ThreadLocal name = new ThreadLocal<>();
    // 定義一個(gè)初始化name成員變量的構(gòu)造器
    public Account(String str)
    {
        this.name.set(str);
        // 下面代碼用于訪問(wèn)當(dāng)前線程的name副本的值
        System.out.println("---" + this.name.get());
    }
    // name的setter和getter方法
    public String getName()
    {
        return name.get();
    }
    public void setName(String str)
    {
        this.name.set(str);
    }
}

class MyTest extends Thread
{
    // 定義一個(gè)Account類型的成員變量
    private Account account;
    public MyTest(Account account, String name)
    {
        super(name);
        this.account = account;
    }
    public void run()
    {
        // 循環(huán)10次
        for (int i = 0 ; i < 10 ; i++)
        {
            // 當(dāng)i == 6時(shí)輸出將賬戶名替換成當(dāng)前線程名
            if (i == 6)
            {
                account.setName(getName());
            }
            // 輸出同一個(gè)賬戶的賬戶名和循環(huán)變量
            System.out.println(account.getName() + " 賬戶的i值:" + i);
        }
    }
}
public class ThreadLocalTest
{
    public static void main(String[] args)
    {
        // 啟動(dòng)兩條線程,兩條線程共享同一個(gè)Account
        Account at = new Account("初始名");
        /*
        雖然兩條線程共享同一個(gè)賬戶,即只有一個(gè)賬戶名
        但由于賬戶名是ThreadLocal類型的,所以每條線程
        都完全擁有各自的賬戶名副本,所以從i == 6之后,將看到兩條
        線程訪問(wèn)同一個(gè)賬戶時(shí)看到不同的賬戶名。
        */
        new MyTest(at, "線程甲").start();
        new MyTest(at, "線程乙").start ();
    }
}

上述程序,由于其中的賬戶名是一個(gè)ThreadLocal變量,所以雖然程序中只有一個(gè)Account對(duì)象,但兩個(gè)子線程將會(huì)產(chǎn)生兩個(gè)賬戶名(主線程持有一個(gè)賬戶名的副本)。程序?qū)嶋H上賬戶名有三個(gè)副本,主線程一個(gè),另外啟動(dòng)的兩個(gè)線程各一個(gè),它們的值互不干擾,每個(gè)線程完全擁有自己的ThreadLocal變量

ThreadLocal將需要并發(fā)訪問(wèn)的資源復(fù)制多份,每個(gè)線程擁有一份資源,每個(gè)線程都擁有自己的資源副本,從而也就沒(méi)有必要對(duì)該變量進(jìn)行同步。ThreadLocal提供了線程安全的共享對(duì)象,在編寫(xiě)多線程代碼時(shí),可把不安全的整個(gè)變量封裝進(jìn)ThreadLocal,或者把該對(duì)象與線程相關(guān)的狀態(tài)使用LocalThread保存

ThreadLocal并不能替代同步機(jī)制,兩者面向的問(wèn)題領(lǐng)域不同。同步機(jī)制是為了同步多個(gè)線程對(duì)相同資源的并發(fā)訪問(wèn),是多個(gè)線程之間進(jìn)行通信的有效方式;而ThreadLocal是為了隔離多個(gè)線程的數(shù)據(jù)共享,從根本上避免多個(gè)線程之間對(duì)共享資源的競(jìng)爭(zhēng)

如果多個(gè)線程之間需要共享資源,以達(dá)到線程之間的通信功能就使用同步機(jī)制;如果僅僅需要隔離多個(gè)線程之間的共享沖突,則可以使用ThreadLocal

包裝線程不安全的集合

對(duì)于Set、List、Queue和Map四種集合,最常用的是HashSet、TreeSet、ArrayList、ArrayQueue、LinkedList和HashMap、TreeMap等實(shí)現(xiàn)類。其中Vector、HashTable、Properties是線程安全的。其中ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等都是線程不安全的,當(dāng)多個(gè)并發(fā)向這些集合中存、取元素時(shí),就可能會(huì)破壞這些集合的數(shù)據(jù)完整性

使用Collections提供的類方法把這些集合包裝成線程安全的集合。Collections提供了如下幾個(gè)靜態(tài)方法:

Collection synchronizedCollection(Collection c):返回指定collection對(duì)應(yīng)的線程安全的collection

static List synchronizedList(List list):返回指定List對(duì)象對(duì)應(yīng)的線程安全的List對(duì)象

static Map synchronizedMap(Map m):返回指定Map對(duì)象對(duì)應(yīng)的線程安全的Map對(duì)象

static Set synchronizedSet(Set s):返回指定Set對(duì)象對(duì)應(yīng)的線程安全的Set對(duì)象

static SortedMap synchronizedSortedMap(SortedMap m):返回指定SortedMap對(duì)象對(duì)應(yīng)的線程安全的SortedMap對(duì)象

static SortedSet synchronizedSortedSet(SortedSet s):返回指定SortedSet對(duì)象對(duì)應(yīng)的線程安全的SortedSet對(duì)象

例如需要在多線程里使用線程安全的HashMap對(duì)象(如果需要把某個(gè)集合包裝成線程安全的集合,則應(yīng)該在創(chuàng)建之后立即包裝,如下程序所示),則可以采用如下代碼:

// 使用Collections 的 synchronizedMap 方法將一個(gè)普通的HashMap包裝成線程安全的類
HashMap m = Collections.synchronizedMap(new HashMap());

線程安全的集合類

java.util.concurrent包下提供了大量支持高效并發(fā)訪問(wèn)的集合接口和實(shí)現(xiàn)類:

線程安全的集合類可以分為兩類:

以Concurrent開(kāi)頭的集合類,如ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、ConcurrentLinkedQueue和ConcurrentLinkedDeque

以CopyOnWrite開(kāi)頭的集合類,如CopyOnWriteArrayList、CopyOnWriteArraySet

Concurrent開(kāi)頭的集合類

其中以Concurrent開(kāi)頭的集合類代表了支持并發(fā)訪問(wèn)的集合,它們可以支持多個(gè)線程并發(fā)寫(xiě)入訪問(wèn),這些寫(xiě)入線程的所有操作都是線程安全的,但讀取操作不必鎖定

當(dāng)多個(gè)線程共享訪問(wèn)一個(gè)公共集合時(shí),ConcurrentLinkedQueue是一個(gè)恰當(dāng)?shù)倪x擇。它不允許null元素,實(shí)現(xiàn)了多線程的高效訪問(wèn),多個(gè)線程訪問(wèn)ConcurrentLinkedQueue集合時(shí)無(wú)需等待

在默認(rèn)情況下,ConcurrentHashMap支持16個(gè)線程并發(fā)寫(xiě)入,當(dāng)有超過(guò)16 個(gè)線程并發(fā)向該Map 中寫(xiě)入數(shù)據(jù)時(shí),可能有一些線程需要等待。程序通過(guò)設(shè)置concurrentLevel構(gòu)造參數(shù)(默認(rèn)值為16)來(lái)支持更多的并發(fā)寫(xiě)入線程

CopyOnWrite開(kāi)頭的集合類

由于CopyOnWriteArraySet底層封裝的是CopyOnWriteArrayList, 因此他的實(shí)現(xiàn)機(jī)制完全類似于CopyOnWriteArrayList

CopyOnWriteArrayList采用復(fù)制底層數(shù)組的方式來(lái)實(shí)現(xiàn)寫(xiě)操作

當(dāng)線程對(duì)CopyOnWriteArrayList集合執(zhí)行讀取操作時(shí), 線程會(huì)直接讀取集合本身, 無(wú)須加鎖和阻塞

當(dāng)線程對(duì)CopyOnWriteArrayList集合執(zhí)行寫(xiě)入操作(add/remove/set)時(shí), 該集合會(huì)在底層復(fù)制一份新的數(shù)組, 然后對(duì)新的數(shù)組執(zhí)行寫(xiě)入操作。由于對(duì)CopyOnWriteArrayList的寫(xiě)入是針對(duì)副本執(zhí)行, 因此它是線程安全的

注意: 由于CopyOnWriteArrayList的寫(xiě)入操作需要頻繁的復(fù)制數(shù)組,因此寫(xiě)入性能較差;但由于讀操作不用加鎖(不是同一個(gè)數(shù)組),因此讀操作非常快。綜上所述,CopyOnWriteArrayList適合在讀取操作遠(yuǎn)遠(yuǎn)大于寫(xiě)操作的場(chǎng)景中, 如緩存等

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66735.html

相關(guān)文章

  • Java魔法——Unsafe應(yīng)用解析

    摘要:典型應(yīng)用鎖和同步器框架的核心類,就是通過(guò)調(diào)用和實(shí)現(xiàn)線程的阻塞和喚醒的,而的方法實(shí)際是調(diào)用的方式來(lái)實(shí)現(xiàn)。 前言 Unsafe是位于sun.misc包下的一個(gè)類,主要提供一些用于執(zhí)行低級(jí)別、不安全操作的方法,如直接訪問(wèn)系統(tǒng)內(nèi)存資源、自主管理內(nèi)存資源等,這些方法在提升Java運(yùn)行效率、增強(qiáng)Java語(yǔ)言底層資源操作能力方面起到了很大的作用。但由于Unsafe類使Java語(yǔ)言擁有了類似C語(yǔ)言指針...

    reclay 評(píng)論0 收藏0
  • 我的面試準(zhǔn)備過(guò)程--JVM相關(guān)

    摘要:程序計(jì)數(shù)器程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。它的主要缺點(diǎn)有兩個(gè)一個(gè)是效率問(wèn)題,標(biāo)記和清除過(guò)程的效率都不 Jvm 相關(guān)  類加載機(jī)制 本段參考 http://www.importnew.com/2374... 類加載概念 類加載指的是將類的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個(gè)ja...

    Towers 評(píng)論0 收藏0
  • 【譯】Java 核心內(nèi)容相關(guān)面試題

    摘要:能否聲明一個(gè)內(nèi)容為空的接口可以。能否將接口聲明為不允許,這樣做會(huì)導(dǎo)致編譯錯(cuò)誤。當(dāng)異常沒(méi)有被捕獲時(shí),會(huì)發(fā)生什么當(dāng)前線程所在的線程組會(huì)執(zhí)行一個(gè)叫的方法,最后程序會(huì)異常退出。非靜態(tài)內(nèi)部類可以使用哪些修飾符非靜態(tài)內(nèi)部類可以使用或修飾符。 原文地址 http://www.instanceofjava.com/2014/12/core-java-interview-questions.html 1...

    sunny5541 評(píng)論0 收藏0
  • java

    摘要:多線程編程這篇文章分析了多線程的優(yōu)缺點(diǎn),如何創(chuàng)建多線程,分享了線程安全和線程通信線程池等等一些知識(shí)。 中間件技術(shù)入門教程 中間件技術(shù)入門教程,本博客介紹了 ESB、MQ、JMS 的一些知識(shí)... SpringBoot 多數(shù)據(jù)源 SpringBoot 使用主從數(shù)據(jù)源 簡(jiǎn)易的后臺(tái)管理權(quán)限設(shè)計(jì) 從零開(kāi)始搭建自己權(quán)限管理框架 Docker 多步構(gòu)建更小的 Java 鏡像 Docker Jav...

    honhon 評(píng)論0 收藏0
  • Java相關(guān)

    摘要:本文是作者自己對(duì)中線程的狀態(tài)線程間協(xié)作相關(guān)使用的理解與總結(jié),不對(duì)之處,望指出,共勉。當(dāng)中的的數(shù)目而不是已占用的位置數(shù)大于集合番一文通版集合番一文通版垃圾回收機(jī)制講得很透徹,深入淺出。 一小時(shí)搞明白自定義注解 Annotation(注解)就是 Java 提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法。Annotion(注解) 是一個(gè)接口,程序可以通過(guò)...

    wangtdgoodluck 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<