亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

(四)java多線程之同步基礎(chǔ)ThreadLocal

Lucky_Boy / 3339人閱讀

摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請(qǐng)注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學(xué)自行下載引言之前我們講到都是多線程共享數(shù)據(jù)那么有沒有某一個(gè)共享的變量在這變量里面每個(gè)線程都能擁有自己的屬性呢比如說去旅店開房休息那么這個(gè)旅店就是一個(gè)共享的數(shù)據(jù)但是每個(gè)人開的房間是不一

本人郵箱:
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明網(wǎng)址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經(jīng)全部托管github有需要的同學(xué)自行下載

引言

之前我們講到都是多線程共享數(shù)據(jù).那么有沒有某一個(gè)共享的變量,在這變量里面,每個(gè)線程都能擁有自己的屬性呢?比如說,去旅店開房休息.那么這個(gè)旅店就是一個(gè)共享的數(shù)據(jù),但是每個(gè)人開的房間是不一樣的.這個(gè)要怎么做呢?這里我先試著寫一些

例子1

讓我們編寫一個(gè)程序,主線程開啟十個(gè)子線程,然后每個(gè)子線程都做1~100的累加,都是共享同一個(gè)List,每個(gè)線程占有固定的位置進(jìn)行累加計(jì)算

public class TestMain {

    public static class CalcRunnable implements Runnable{
        List list ;
        int index;
        public CalcRunnable(List list, int index) {
            this.list = list;
            this.index = index;
        }

        @Override
        public void run() {
            for (int i = 1; i <= 100; i++){
                list.set(index, list.get(index) + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        List list = new ArrayList<>();
        List threads = new ArrayList<>();
        for (int i = 0; i < 10; i ++){
            list.add(0);
            threads.add(new Thread(new CalcRunnable(list,i)));
        }
        for (Thread thread : threads){
            thread.start();
        }

        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list);
    }
}

輸出結(jié)果為

[5050, 5050, 5050, 5050, 5050, 5050, 5050, 5050, 5050, 5050]

這里每個(gè)線程都共享了list,但是也沒有使用關(guān)鍵字synchronized進(jìn)行同步,為什么結(jié)果還是正確的呢?原因很簡單,那就是每個(gè)線程都使用固定的索引進(jìn)行計(jì)算,互不干擾.所以結(jié)果不會(huì)受其他線程影響的.

例子2

現(xiàn)在把上面的例子中的List改為Map來做累加

public class TestMain1 {

    public static class CalcRunnable implements Runnable{
        Map map;
        public CalcRunnable(Map map) {
            this.map = map;
        }

        @Override
        public void run() {
            Thread self = Thread.currentThread();
            for (int i = 1; i <= 100; i++){
                map.put(self, map.get(self) + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        Map map = new HashMap<>();
        List threads = new ArrayList<>();
        for (int i = 0; i < 10; i ++){
            Thread thread = new Thread(new CalcRunnable(map));
            map.put(thread,0);
            threads.add(thread);
        }
        for (Thread thread : threads){
            thread.start();
        }

        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(map);
    }
}

運(yùn)行結(jié)果

{Thread[Thread-1,5,]=5050, Thread[Thread-3,5,]=5050, Thread[Thread-6,5,]=5050, Thread[Thread-0,5,]=5050, Thread[Thread-8,5,]=5050, Thread[Thread-5,5,]=5050, Thread[Thread-7,5,]=5050, Thread[Thread-2,5,]=5050, Thread[Thread-4,5,]=5050, Thread[Thread-9,5,]=5050}

結(jié)果也是完全正確,道理跟上面的例子一樣,每個(gè)線程雖然共用同一個(gè)數(shù)據(jù)map,但實(shí)際上每個(gè)線程都是用map中特定的那個(gè)元素

例子3

其實(shí)用map還有一種更簡單的方式,那就是今天要講的ThreadLocal,不廢話,看例子

public class TestMain3 {

    public static class CalcRunnable implements Runnable{
        ThreadLocal threadLocal;
        public CalcRunnable(ThreadLocal threadLocal) {
            this.threadLocal = threadLocal;
        }

        @Override
        public void run() {
            threadLocal.set(0);//設(shè)置默認(rèn)值
            for (int i = 1; i <= 100; i++){
                threadLocal.set(threadLocal.get() + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + " 的計(jì)算結(jié)果為: " + threadLocal.get());
        }
    }

    public static void main(String[] args) {
        ThreadLocal threadLocal = new ThreadLocal<>();
        List threads = new ArrayList<>();
        for (int i = 0; i < 10; i ++){
            Thread thread = new Thread(new CalcRunnable(threadLocal));
            threads.add(thread);
        }
        for (Thread thread : threads){
            thread.start();
        }
    }
}

運(yùn)行結(jié)果

Thread-0 的計(jì)算結(jié)果為: 5050
Thread-5 的計(jì)算結(jié)果為: 5050
Thread-1 的計(jì)算結(jié)果為: 5050
Thread-4 的計(jì)算結(jié)果為: 5050
Thread-7 的計(jì)算結(jié)果為: 5050
Thread-6 的計(jì)算結(jié)果為: 5050
Thread-3 的計(jì)算結(jié)果為: 5050
Thread-2 的計(jì)算結(jié)果為: 5050
Thread-8 的計(jì)算結(jié)果為: 5050
Thread-9 的計(jì)算結(jié)果為: 5050

原理,其實(shí)就是跟例子2的Map,在ThreadLocal中實(shí)現(xiàn)了一個(gè)ThreadLocalMap內(nèi)部類,然后在調(diào)用ThreadLocal.getThreadLocal.set的時(shí)候,其實(shí)要獲取當(dāng)前線程去做相應(yīng)的操作.

總結(jié)

如果以后大家想讓多線程共享一個(gè)變量,但又不想互相影響的時(shí)候,那么首選ThreadLocal.因?yàn)閷?duì)比上面三個(gè)例子,發(fā)現(xiàn)使用ThreadLocal是最簡單的,而且不容易出錯(cuò)的.比如在web開發(fā)中,可以在多線程中存放session,或者數(shù)據(jù)庫連接池的時(shí)候,也可以使用ThreadLocal在存放數(shù)據(jù)庫連接.

打賞

如果覺得我的文章寫的還過得去的話,有錢就捧個(gè)錢場(chǎng),沒錢給我捧個(gè)人場(chǎng)(幫我點(diǎn)贊或推薦一下)

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

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

相關(guān)文章

  • java高并發(fā)從零到放棄(

    摘要:前言本篇主要講解如何去優(yōu)化鎖機(jī)制或者克服多線程因?yàn)殒i可導(dǎo)致性能下降的問題線程變量有這樣一個(gè)場(chǎng)景,前面是一大桶水,個(gè)人去喝水,為了保證線程安全,我們要在杯子上加鎖導(dǎo)致大家輪著排隊(duì)喝水,因?yàn)榧恿随i的杯子是同步的,只能有一個(gè)人拿著這個(gè)唯一的杯子喝 前言 本篇主要講解如何去優(yōu)化鎖機(jī)制或者克服多線程因?yàn)殒i可導(dǎo)致性能下降的問題 ThreadLocal線程變量 有這樣一個(gè)場(chǎng)景,前面是一大桶水,10個(gè)...

    Alex 評(píng)論0 收藏0
  • Java線程同步與阻塞隊(duì)列

    摘要:注意,和都是隨機(jī)選擇一個(gè)線程,解除其阻塞狀態(tài),可能會(huì)造成死鎖。生產(chǎn)者線程向隊(duì)列插入元素,消費(fèi)者線程從隊(duì)列取出元素。當(dāng)添加時(shí)隊(duì)列已滿或取出時(shí)隊(duì)列為空,阻塞隊(duì)列導(dǎo)致線程阻塞。里面有個(gè)小技巧,一個(gè)線程搜索完畢時(shí)向阻塞隊(duì)列填充,讓所有線程能停下來。 多線程對(duì)共享數(shù)據(jù)的讀寫涉及到同步問題,鎖和條件是線程同步的強(qiáng)大工具。鎖用來保護(hù)代碼片段(臨界區(qū)),任何時(shí)刻只能有一個(gè)線程執(zhí)行被保護(hù)的代碼。條件對(duì)象...

    Olivia 評(píng)論0 收藏0
  • 想進(jìn)大廠?50個(gè)線程面試題,你會(huì)少?(一)

    摘要:下面是線程相關(guān)的熱門面試題,你可以用它來好好準(zhǔn)備面試。線程安全問題都是由全局變量及靜態(tài)變量引起的。持有自旋鎖的線程在之前應(yīng)該釋放自旋鎖以便其它線程可以獲得自旋鎖。 最近看到網(wǎng)上流傳著,各種面試經(jīng)驗(yàn)及面試題,往往都是一大堆技術(shù)題目貼上去,而沒有答案。 不管你是新程序員還是老手,你一定在面試中遇到過有關(guān)線程的問題。Java語言一個(gè)重要的特點(diǎn)就是內(nèi)置了對(duì)并發(fā)的支持,讓Java大受企業(yè)和程序員...

    wow_worktile 評(píng)論0 收藏0
  • Java線程基礎(chǔ)-ThreadLocal

    摘要:并沒有提供語言級(jí)的線程局部變量,而是在類庫里提供了線程局部變量的功能,也就是這次的主角類。 Yuicon 轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝! 序 在多線程環(huán)境下,訪問非線程安全的變量時(shí)必須進(jìn)行線程同步,例如使用synchronized方式訪問HashMap實(shí)例。但是同步訪問會(huì)降低并發(fā)性,影響系統(tǒng)性能。這時(shí)候就可以用空間換時(shí)間,如果我們給每個(gè)線程都分配一個(gè)獨(dú)立的變量,就可以用非同步的方式使用非...

    JasonZhang 評(píng)論0 收藏0
  • Java面試題必備知識(shí)ThreadLocal

    摘要:方法,刪除當(dāng)前線程綁定的這個(gè)副本數(shù)字,這個(gè)值是的值,普通的是使用鏈表來處理沖突的,但是是使用線性探測(cè)法來處理沖突的,就是每次增加的步長,根據(jù)參考資料所說,選擇這個(gè)數(shù)字是為了讓沖突概率最小。 showImg(https://segmentfault.com/img/remote/1460000019828633); 老套路,先列舉下關(guān)于ThreadLocal常見的疑問,希望可以通過這篇學(xué)...

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

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

0條評(píng)論

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