【java基礎(chǔ)】線程

java基礎(chǔ) 線程

參考詳細(xì):Java之多線程

一礼搁、創(chuàng)建線程

創(chuàng)建線程常見有兩種方式望浩,另外有兩種新增方式

1.Thread

    /**
    新建線程方式一:繼承Thread蓖宦,重寫run()
     */
    public static void test1(){
        Thread1 thread1 = new Thread1();
        thread1.setName("thread1");
        thread1.start();
    }

    static class Thread1 extends Thread{
        int i;
        @Override
        public void run() {
            while (i < 100){
                ++i;
                System.out.println(this.getName() + " 優(yōu)先級(jí) "+this.getPriority()+":" + i);
            }
        }
    }

2.Runnable

     /**
     * 新建線程方式二:實(shí)現(xiàn)Runnable有序,實(shí)現(xiàn)run();將Runnable作為Thread創(chuàng)建的實(shí)參
     */
    public static void test2(){
        Runnable runnable = new Runnable() {
            int i;
            @Override
            public void run() {
                while (i < 100){
                    ++i;
                    System.out.println(Thread.currentThread().getName() + " 優(yōu)先級(jí) "+Thread.currentThread().getPriority()+":" + i);
                }
            }
        };
        Thread thread2 = new Thread(runnable,"thread2");
        thread2.start();
    }

3.Callable --- JDK5.0新增

     /**
     * 新增·方式三:實(shí)現(xiàn)Callable接口,此功能支持有泛型返回值蜻拨,支持拋出異常,需借助FutureTask類
     */
    public static void test3() throws ExecutionException, InterruptedException {
        Callable callable = getCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        Thread thread3 = new Thread(futureTask);
        thread3.start();

        // 返回值
        Integer integer = futureTask.get();
        System.out.println("方式三:main獲得結(jié)果-"+integer);
    }

    private static Callable getCallable(){
        Callable<Integer> callable = new Callable<Integer>() {
            int i;
            @Override
            public Integer call() throws Exception {
                while (i < 100){
                    ++i;
                    System.out.println(Thread.currentThread().getName() + " 優(yōu)先級(jí) "+Thread.currentThread().getPriority()+":" + i);
                }
                return i;
            }
        };
        return callable;
    }

4.ThreadPool --- JDK5.0新增

     /**
     * 新增·方式四:使用線程池創(chuàng)建線程
     */
    public static void test4() throws ExecutionException, InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(5);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor)service;
        Callable callable = getCallable();
        Future future = service1.submit(callable);
        System.out.println("方式四:main獲得結(jié)果-"+future.get());
        service.shutdown();
    }

     private static Callable getCallable(){
        Callable<Integer> callable = new Callable<Integer>() {
            int i;
            @Override
            public Integer call() throws Exception {
                while (i < 100){
                    ++i;
                    System.out.println(Thread.currentThread().getName() + " 優(yōu)先級(jí) "+Thread.currentThread().getPriority()+":" + i);
                }
                return i;
            }
        };
        return callable;
    }

步驟:

1)提供指定線程池
ExecutorService service = Executors.newXXXThreadPool()

設(shè)置線程池屬性
ThreadPoolExecutor service1 = ()service;
service1.setXXX

2)執(zhí)行指定線程的操作桩引,需要提供實(shí)現(xiàn)Runnable接口或Callable接口庫實(shí)現(xiàn)類的對象
service.execute(xxx); // xxx為實(shí)現(xiàn)Runnable接口的類的對象
service.submit(xxx); // xxx為實(shí)現(xiàn)Callable接口的類的對象缎讼,返回結(jié)果Future類

3)關(guān)閉連接池
service.shutdown();

二、線程屬性方法

1.Thread類的有關(guān)方法

1)start():啟動(dòng)當(dāng)前線程坑匠,調(diào)用當(dāng)前線程的run()
2)run():通常需要重寫Thread類中的此方法血崭,將創(chuàng)建的線程需要處理的邏輯寫在這里
3)currentThread():靜態(tài)方法,返回執(zhí)行當(dāng)前代碼的線程 this = Thread.currentThread()
4)getName():獲得當(dāng)前線程的名字
5)setName():設(shè)置當(dāng)前線程的名字
6)yield():釋放當(dāng)前cpu的執(zhí)行權(quán)
7)join():在線程a中調(diào)用線程b的join()厘灼,此時(shí)線程a就進(jìn)入阻塞狀態(tài)夹纫,直到線程b完全執(zhí)行完成以后,線程a就是阻塞狀態(tài)
8)stop():已過時(shí)设凹。當(dāng)執(zhí)行此方法舰讹,強(qiáng)制結(jié)束當(dāng)前線程
9)sleep(long millitime):讓當(dāng)前線程“睡眠”指定millitime毫秒。在指定的毫秒內(nèi)闪朱,當(dāng)前線程阻塞狀態(tài)月匣。
10)isAlive():判斷當(dāng)前線程是否存活

2.線程優(yōu)先級(jí)

1)等級(jí):
MAX_PRIORITY:10,MIN_PRIORITY:1奋姿,NORM_PRIORITY:5
2)如何獲取和設(shè)置當(dāng)前線程優(yōu)先級(jí)
getPriority():獲取當(dāng)前線程優(yōu)先級(jí)
setProority(int p):設(shè)置當(dāng)前線程優(yōu)先級(jí)
高優(yōu)先級(jí)線程要搶占低優(yōu)先級(jí)線程cpu執(zhí)行權(quán)锄开。但是只是從概率上講。

3.生命周期

線程生命周期.png

yield()

  • yield() 讓當(dāng)前正在運(yùn)行的線程回到可運(yùn)行狀態(tài)称诗,以允許具有相同優(yōu)先級(jí)的其他線程獲得運(yùn)行的機(jī)會(huì)萍悴。因此,使用yield()的目的是讓具有相同優(yōu)先級(jí)的線程之間能夠適當(dāng)?shù)妮啌Q執(zhí)行寓免。但是退腥,實(shí)際中無法保證yield()達(dá)到讓步的目的,因?yàn)樵匍尣降木€程可能被線程調(diào)度程序再次選中

4.線程通信

方法

1)wait():使得調(diào)用wait()的線程進(jìn)入阻塞狀態(tài)狡刘,并釋放同步監(jiān)視器
2)notify():一旦執(zhí)行此方法,就會(huì)喚醒被wait的一個(gè)線程困鸥。如果多個(gè)線程被wait嗅蔬,喚醒優(yōu)先級(jí)高的
3)notifyAll():一旦執(zhí)行此方法剑按,就會(huì)喚醒被wait的所有線程

說明

1)wait(),notiry()澜术,notiryAll()需要聲明在同步代碼塊或者同步代碼方法中
2)wait()艺蝴,notiry(),notiryAll()調(diào)用者必須是同步代碼塊或者同步代碼方法的同步監(jiān)視器鸟废,否則會(huì)出現(xiàn)異常
3)wait()猜敢,notiry(),notiryAll()聲明在java.lang.Object當(dāng)中

sleep() VS wait()

  • sleep() 方法是線程類(Thread)的靜態(tài)方法盒延,調(diào)用此方法讓當(dāng)前線程暫停執(zhí)行指定的時(shí)間缩擂,將執(zhí)行機(jī)會(huì)(CPU)讓給其他線程,但是對象的鎖依然保持添寺,因此休眠時(shí)間結(jié)束后會(huì)自動(dòng)恢復(fù)(線程回到就緒狀態(tài))
  • wait() 是Object類的方法胯盯,調(diào)用對象的wait()方法導(dǎo)致當(dāng)前線程放棄對象的鎖(線程暫停執(zhí)行),進(jìn)入對象的等待池(wait pool)计露,只有調(diào)用對象的notify()方法(或notifyAll()方法)時(shí)才能喚醒等待池中的線程進(jìn)入等鎖池(lock pool)博脑,如果線程重新獲得對象的鎖就可以進(jìn)入就緒狀態(tài)

總結(jié)

  • 不同:sleep()鎖在,wait()鎖不在票罐。sleep()時(shí)間結(jié)束自動(dòng)恢復(fù)叉趣;wait()等待notify()(或notifyAll()方法)喚醒
  • 同:調(diào)用方法進(jìn)入阻塞狀態(tài)

三、線程同步機(jī)制

1.同步代碼塊

synchronized(同步監(jiān)視器){
      //需要同步的代碼
}

同步監(jiān)視器:類的對象
要求:多個(gè)線程必須要共用同一把鎖该押,可以考慮使用this疗杉,類.class等

2.同步方法

synchronized添加到方法
synchronized method():同步監(jiān)視器是this
static synchronized method():同步監(jiān)視器是類.class

3.Lock鎖 --- JDK5.0新增

  • 從JDK 5.0開始,Java提供了更強(qiáng)大的線程同步機(jī)制--通過顯式定義同步鎖對象來實(shí)現(xiàn)同步沈善。同步鎖使用Lock對象充當(dāng)乡数。
  • java.util.concurrent.locks.Lock接口是控制多個(gè)線程對共享資源進(jìn)行訪問的工具。鎖提供了對共享資源的獨(dú)占訪問闻牡,每次只能有一個(gè)線程對Lock對象加鎖净赴,線程開始訪問共享資源之前應(yīng)先獲得Lock對象。
  • ReentrantLock類實(shí)現(xiàn)了Lock罩润,它擁有與 synchronized相同的并發(fā)性和內(nèi)存語義玖翅,在實(shí)現(xiàn)線程安全的控制中,比較常用的是 Reentrantlock割以,可以顯式加鎖金度、釋放鎖
class A {
    //1.實(shí)例化ReentrantLock對象
    private final ReenTrantLock lock = new ReenTrantLook();
    public void m (){
        lock.lock//2.先加鎖
        try{
            //保證線程同步的代碼
        }finally{
            lock.unlock();//3.后解鎖
        }
    }
}

//注意:如果同步代碼塊有異常,要將unlock()寫入finally語句塊中
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末严沥,一起剝皮案震驚了整個(gè)濱河市猜极,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌消玄,老刑警劉巖跟伏,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丢胚,死亡現(xiàn)場離奇詭異,居然都是意外死亡受扳,警方通過查閱死者的電腦和手機(jī)携龟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門睦柴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來围肥,“玉大人盅弛,你說我怎么就攤上這事胁孙。” “怎么了檩互?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵橡娄,是天一觀的道長拔莱。 經(jīng)常有香客問我立美,道長匿又,這世上最難降的妖魔是什么方灾? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任建蹄,我火速辦了婚禮,結(jié)果婚禮上裕偿,老公的妹妹穿的比我還像新娘洞慎。我一直安慰自己,他們只是感情好嘿棘,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布劲腿。 她就那樣靜靜地躺著,像睡著了一般鸟妙。 火紅的嫁衣襯著肌膚如雪焦人。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天重父,我揣著相機(jī)與錄音花椭,去河邊找鬼。 笑死房午,一個(gè)胖子當(dāng)著我的面吹牛矿辽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播郭厌,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼袋倔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了折柠?” 一聲冷哼從身側(cè)響起宾娜,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扇售,沒想到半個(gè)月后前塔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贾陷,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年嘱根,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了髓废。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡该抒,死狀恐怖慌洪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凑保,我是刑警寧澤冈爹,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站欧引,受9級(jí)特大地震影響频伤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芝此,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一憋肖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧婚苹,春花似錦岸更、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至廓译,卻和暖如春评肆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背非区。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工瓜挽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人院仿。 一個(gè)月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓秸抚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親歹垫。 傳聞我的和親對象是個(gè)殘疾皇子剥汤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 操作系統(tǒng)中線程 線程是程序執(zhí)行的最小單位,而進(jìn)程是操作系統(tǒng)分配資源的最小單位排惨。 一個(gè)進(jìn)程由一個(gè)或多個(gè)線程組成吭敢,線程...
    陳晨_Fly閱讀 450評論 1 6
  • 1、相關(guān)概念 進(jìn)程是指一個(gè)內(nèi)存中運(yùn)行的應(yīng)用程序暮芭,每個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間鹿驼,一個(gè)進(jìn)程中可以啟動(dòng)多個(gè)線程欲低。 ...
    冰河winner閱讀 555評論 0 0
  • 在Java中創(chuàng)建線程有兩種方法:使用Thread類和使用Runnable接口。要注意的是Thread類也實(shí)現(xiàn)了Ru...
    侯廣麗閱讀 515評論 0 0
  • 1.進(jìn)程是程序加載到內(nèi)存之后被cpu計(jì)算的過程 線程是CPU調(diào)度的最小單位 區(qū)別:線程是進(jìn)程的子集,一個(gè)進(jìn)程可...
    不瘋魔丶不成活z閱讀 258評論 0 0
  • synchronized實(shí)現(xiàn)原理 在java代碼中使用synchronized可是使用在代碼塊和方法中畜晰,根據(jù)Syn...
    16325閱讀 173評論 0 0