国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

設(shè)計(jì)模式(單例模式,工廠(chǎng)模式),線(xiàn)程池

這篇具有很好參考價(jià)值的文章主要介紹了設(shè)計(jì)模式(單例模式,工廠(chǎng)模式),線(xiàn)程池。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

什么是設(shè)計(jì)模式?

單例模式

餓漢模式

懶漢模式

工廠(chǎng)模式

線(xiàn)程池

線(xiàn)程池種類(lèi)

ThreadPoolExcutor的構(gòu)造方法:

手動(dòng)實(shí)現(xiàn)一個(gè)線(xiàn)程池?


什么是設(shè)計(jì)模式?

計(jì)算機(jī)行業(yè)程序員水平層次不齊,為了讓所有人都能夠?qū)懗鲆?guī)范的代碼,于是就有了設(shè)計(jì)模式,針對(duì)一些典型的場(chǎng)景,給出一些典型的解決方案

單例模式

單例模式 ==> 單個(gè)實(shí)例(對(duì)象)

在一些場(chǎng)景中,有的特定類(lèi)只能創(chuàng)建一個(gè)實(shí)例,不能創(chuàng)建多個(gè)實(shí)例
使用了單例模式后,此時(shí)就不能創(chuàng)建多個(gè)實(shí)例了,我們想創(chuàng)建多個(gè)實(shí)例都難,單例模式就是針對(duì)上述的需求場(chǎng)景進(jìn)行了更強(qiáng)制的保證,通過(guò)巧用java的語(yǔ)法,達(dá)成某個(gè)類(lèi) 只能被創(chuàng)建出一個(gè)實(shí)例這樣的效果(當(dāng)程序員不小心創(chuàng)建了多個(gè)實(shí)例,就會(huì)報(bào)錯(cuò))

單例模式實(shí)現(xiàn)

餓漢模式

// 餓漢模式的 單例模式 實(shí)現(xiàn)
// 此處保證 Singleton 這個(gè)類(lèi)只能創(chuàng)建出一個(gè)實(shí)例
class Singleton{
    // 在此處,先把實(shí)例給創(chuàng)建出來(lái)
    private static Singleton instance = new Singleton();

    // 如果需要使用 instance,通過(guò)統(tǒng)一的Singleton.getInstance() 方式獲取
    public static Singleton getInstance(){
        return instance;
    }

    // 為了避免 Singleton 類(lèi)不小心被復(fù)制多份
    // 把構(gòu)造方法設(shè)為 private,在類(lèi)外面,就無(wú)法通過(guò)new 的方式來(lái)創(chuàng)建這個(gè) Singleton了
    private Singleton(){};
}
public class Thread3 {
    public static void main(String[] args) {
        Singleton s = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s==s2);
        Singleton s3 = new Singleton(); // 報(bào)錯(cuò),原因是Singleton的構(gòu)造方法被private修飾,因此無(wú)法通過(guò)new的方式創(chuàng)建Singleton對(duì)象
    }
}

懶漢模式

class Singleton2{ 
    private static volatile Singleton2 instance = null; //使用volatile表示instance是個(gè)易變的

    public static Singleton2 getInstance(){
        if (instance==null) {   // 此處負(fù)責(zé)判斷是否要加鎖
            synchronized (Singleton2.class) {
                if(instance==null){   // 此處判斷是否要?jiǎng)?chuàng)建對(duì)象
                    instance = new Singleton2();
                }
            }
        }
        return instance;
    }

    private Singleton2(){};
}

懶漢模式下,有創(chuàng)建Singleton對(duì)象的操作(寫(xiě)操作),所以可能會(huì)出現(xiàn)線(xiàn)程安全問(wèn)題,因此我們要進(jìn)行加鎖操作,并標(biāo)注instance是一個(gè)易變的對(duì)象(避免內(nèi)存可見(jiàn)性問(wèn)題,和指令重排序問(wèn)題)

工廠(chǎng)模式

工廠(chǎng)模式: 使用普通的方法,來(lái)代替構(gòu)造方法,創(chuàng)建對(duì)象.? 在java中,構(gòu)造方法存在一定缺陷,構(gòu)造方法要求構(gòu)造名必須為類(lèi)名(方法名相同),構(gòu)造參數(shù)可以不同,沒(méi)用返回值.如果我們只構(gòu)造一種對(duì)象可以忽略這個(gè)缺陷,如果構(gòu)造多種不同的情況的對(duì)象可能會(huì)出現(xiàn)問(wèn)題,比如想要實(shí)現(xiàn)倆個(gè)不同的構(gòu)造方法,但是它們的參數(shù)類(lèi)型恰好都相同,但表達(dá)的意義不同,這時(shí)java就無(wú)法區(qū)分了.為了解決這個(gè)問(wèn)題,就可以使用工程模式

比如分別使用笛卡爾坐標(biāo)系和極坐標(biāo)系表示坐標(biāo)

import java.awt.*;
class PointFactory{
    public static Point makePointByXY(double x,double y){}
    public static Point makePointByRA(double r,double a){}
}
public class Thread6 {
    public static void main(String[] args) {
        Point p = PointFactory.makePointByXY(10,20);
        Point p2 = PointFactory.makePointByRA(10,30);
    }
}

線(xiàn)程池

線(xiàn)程存在的意義: 使用進(jìn)程實(shí)現(xiàn)并發(fā)編程,"太重了",引入線(xiàn)程(輕量級(jí)進(jìn)程),創(chuàng)建線(xiàn)程比創(chuàng)建線(xiàn)程更高效,銷(xiāo)毀線(xiàn)程比銷(xiāo)毀進(jìn)程更高效,調(diào)度線(xiàn)程比調(diào)度進(jìn)程更高效,此時(shí)使用多線(xiàn)程就可以在很多時(shí)候代替進(jìn)程實(shí)現(xiàn)并發(fā)編程了

線(xiàn)程池存在的意義: 當(dāng)我們需要頻繁創(chuàng)建銷(xiāo)毀線(xiàn)程的時(shí)候,就發(fā)現(xiàn)開(kāi)銷(xiāo)也很大,想要進(jìn)一步的提高效率,可以: 1.搞一個(gè)協(xié)程(輕量級(jí)線(xiàn)程) 2.使用線(xiàn)程池,事先把需要使用的線(xiàn)程創(chuàng)建好,放到池中,后面需要使用的時(shí)候,從池中獲取,如果用完了,再還給池.(創(chuàng)建線(xiàn)程和銷(xiāo)毀線(xiàn)程是交由操作系統(tǒng)內(nèi)核去完成的,從池子里獲取/還給池,是自己用戶(hù)代碼就能實(shí)現(xiàn)的,不必交給內(nèi)核操作)

public class Thread5 {
    public static void main(String[] args) {
        // 此處就構(gòu)造了一個(gè) 10 個(gè)線(xiàn)程的線(xiàn)程池,就可以隨時(shí)安排這些線(xiàn)程干活了
       ExecutorService pool =  Executors.newFixedThreadPool(10);
       // 當(dāng)前往線(xiàn)程池中放了1000個(gè)任務(wù),這1000個(gè)任務(wù)由線(xiàn)程池中的10個(gè)線(xiàn)程去執(zhí)行
        for (int i = 0;i < 1000;i++) {
            pool.submit(()->{
                System.out.println("hello");
            });
        }
    }
}

線(xiàn)程池提供了一個(gè)重要的方法,submit,可以給線(xiàn)程池提交若干個(gè)任務(wù),這若干個(gè)任務(wù)可以由線(xiàn)程池中的線(xiàn)程去執(zhí)行完成..線(xiàn)程池中創(chuàng)建的線(xiàn)程是前臺(tái)線(xiàn)程,需要執(zhí)行完成后,主線(xiàn)程才可以結(jié)束.?
這里1000個(gè)任務(wù)相當(dāng)于在一個(gè)隊(duì)列中,線(xiàn)程池中的這10個(gè)線(xiàn)程就依次取這個(gè)隊(duì)列中的任務(wù),取一個(gè)就執(zhí)行一個(gè),執(zhí)行完成后,再在這個(gè)隊(duì)列中取任務(wù)去執(zhí)行?

線(xiàn)程池種類(lèi)

設(shè)計(jì)模式(單例模式,工廠(chǎng)模式),線(xiàn)程池,設(shè)計(jì)模式,單例模式

這些線(xiàn)程池,本質(zhì)上都是通過(guò)包裝 ThreadPoolExecutor 來(lái)實(shí)現(xiàn)的?

ThreadPoolExcutor的構(gòu)造方法:

設(shè)計(jì)模式(單例模式,工廠(chǎng)模式),線(xiàn)程池,設(shè)計(jì)模式,單例模式

corePoolSize : 核心線(xiàn)程數(shù),

maximumPoolSize:? 最大線(xiàn)程數(shù),相當(dāng)于線(xiàn)程池把線(xiàn)程分為倆大類(lèi),一類(lèi)是核心線(xiàn)程,一類(lèi)是非核心線(xiàn)程,最大線(xiàn)程數(shù)就是核心線(xiàn)程和非核心線(xiàn)程之和
一個(gè)程序有時(shí)任務(wù)多,有時(shí)任務(wù)少,如果任務(wù)多,我們就需要多一些線(xiàn)程,如果任務(wù)少,就需要線(xiàn)程盡量少,此時(shí)我們就可以保留核心線(xiàn)程,而淘汰掉一些非核心線(xiàn)程

實(shí)際開(kāi)發(fā)中,線(xiàn)程池的線(xiàn)程數(shù)設(shè)定成多少合適?

程序分為CPU密集型,每個(gè)線(xiàn)程執(zhí)行的任務(wù)都需要狂轉(zhuǎn)CPU(進(jìn)行一系列算術(shù)運(yùn)算),此時(shí)線(xiàn)程池線(xiàn)程數(shù)最多不超過(guò)CPU核數(shù),因?yàn)閏pu密集型要一直占用cpu,創(chuàng)建更多的線(xiàn)程也沒(méi)用
IO密集型,每個(gè)線(xiàn)程的工作就是等待IO(讀寫(xiě)硬盤(pán),讀寫(xiě)網(wǎng)卡,等待用戶(hù)輸入),不占CPU,此時(shí)這樣的線(xiàn)程處于阻塞狀態(tài),不參與CPU調(diào)度,這個(gè)時(shí)候創(chuàng)建多個(gè)線(xiàn)程,不再受制于CPU核數(shù)了
實(shí)踐中確定線(xiàn)程數(shù),通過(guò)實(shí)驗(yàn)的方式,康康設(shè)置幾個(gè)線(xiàn)程合適

long keepAliveTime: 非核心線(xiàn)程數(shù)不工作的最大時(shí)間,如果超過(guò)這個(gè)時(shí)間就銷(xiāo)毀

TimeUnit unit: 時(shí)間單位,ms,s,分鐘,小時(shí)......

BlockingQueue<Runnable> workQueue: 線(xiàn)程池的任務(wù)隊(duì)列

ThreadFactory threadFactory: 用于創(chuàng)建線(xiàn)程

RejectedExecutionHandler handler: 描述了線(xiàn)程池的"拒絕策略",是一個(gè)特殊的對(duì)象,描述了當(dāng)線(xiàn)程池任務(wù)隊(duì)列滿(mǎn)了之后,如果繼續(xù)添加任務(wù),線(xiàn)程池會(huì)有什么樣的行為,總共有以下4種策略
ThreadPoolExcutor.AbortPolicy: 如果任務(wù)隊(duì)列滿(mǎn)了,再新增任務(wù),直接拋出異常
ThreadPoolExcutor.CallerRunsPoliy: 如果任務(wù)隊(duì)列滿(mǎn)了,多出來(lái)的任務(wù),誰(shuí)加的就由誰(shuí)去執(zhí)行(交給調(diào)用者去執(zhí)行)
ThreadPoolExcutor.DisardOlderdestPolicy: 如果任務(wù)隊(duì)列滿(mǎn)了,就丟棄最老的任務(wù)
ThreadPoolExcutor.DiscardPolicy: 如果任務(wù)隊(duì)列滿(mǎn)了,就丟棄最新的任務(wù)

手動(dòng)實(shí)現(xiàn)一個(gè)線(xiàn)程池?

一個(gè)線(xiàn)程池中至少有倆個(gè)部分,一個(gè)是阻塞隊(duì)列,用來(lái)保存任務(wù),一個(gè)是若干個(gè)工作線(xiàn)程文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-670484.html

class MyThreadPool{
    private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();

    // n 表示線(xiàn)程數(shù)量
    public MyThreadPool(int n){
        // 創(chuàng)建 n 個(gè)線(xiàn)程
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(()->{
                while (true){
                    try {
                       Runnable runnable =  queue.take();
                       runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
    }

    // 注冊(cè)任務(wù)交給線(xiàn)程池
    public void submit(Runnable runnable) {
        try {
            queue.put(runnable);
        } catch (InterruptedException e) {
                e.printStackTrace();
        }
    }
}

到了這里,關(guān)于設(shè)計(jì)模式(單例模式,工廠(chǎng)模式),線(xiàn)程池的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀(guān)點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包