Java語言的學(xué)習(xí)與實(shí)踐11 (線程脑溢,進(jìn)程,線程安全)

1.收獲

慢慢的java學(xué)習(xí)階段快要進(jìn)入結(jié)束階段赖欣,馬上就要進(jìn)入Andriod階段屑彻,在這段學(xué)習(xí)的期間,說實(shí)話學(xué)到的東西是很多的顶吮,包括沒有在學(xué)校的課堂學(xué)到的東西社牲,在這個(gè)階段自己雖然沒有發(fā)現(xiàn)自己有多大的變化但是我認(rèn)為在這個(gè)階段沒有進(jìn)行而太多的實(shí)際操作,很多的東西還是在理論的水平悴了。不管怎樣自己一定要努力搏恤,希望時(shí)間值得!

2.技術(shù)

(1)進(jìn)程
(2)線程
(3)線程安全

3.技術(shù)的實(shí)際應(yīng)用和實(shí)踐

(1)進(jìn)程
什么是進(jìn)程:
根據(jù)我自己的理解就是正在運(yùn)行的一個(gè)程序 QQ IDE 瀏覽器, 并且系統(tǒng)會(huì)為這個(gè)進(jìn)程分配獨(dú)立的內(nèi)存資源湃交。
可以同時(shí)多個(gè)進(jìn)程運(yùn)行熟空。

(2)線程
什么是線程:
具體執(zhí)行任務(wù)的最小單位,在Andriod中顯示界面稱為UI主線程搞莺,一個(gè)進(jìn)程最少擁有一個(gè)線程 (主線程 運(yùn)行起來就執(zhí)行的線程)息罗,線程之間是共享同一片內(nèi)存資源的(進(jìn)程申請的),線程之間可以通信的(數(shù)據(jù)傳遞:多數(shù)為主線程和子線程)腮敌,每一個(gè)線程都有自己的運(yùn)行回路(生命周期)阱当。

** 線程的生命周期**
狀態(tài)

  • NEW:新建 線程剛被創(chuàng)建好
  • RUNNABLE:就緒狀態(tài) 只要搶到時(shí)間片就可以運(yùn)行這個(gè)線程
  • BLOCKED:阻塞狀態(tài) wait sleep
  • WAITING:等待 wait
  • TIMED_WAITING:處在TIMED_WAITING的線程,如果特定的事件發(fā)生或者是時(shí)間流逝完畢糜工,都會(huì)恢復(fù)運(yùn)行弊添。
  • TERMINATED:終止?fàn)顟B(tài)
353507101400421.png

線程執(zhí)行

QQ圖片20190818141122.png

子線程
為什么要?jiǎng)?chuàng)建子線程:
如果在主線程存在又比較耗時(shí)的操作 :下載視頻 上傳文件 數(shù)據(jù)處理 ,這些會(huì)阻塞主線程捌木,后面的任務(wù)必須等待這些任務(wù)執(zhí)行完畢之后才能執(zhí)行油坝,用戶體驗(yàn)比較差,為了不阻塞主線程,需要將耗時(shí)的任務(wù)放在子線程中去處理。

如何創(chuàng)建子線程:
兩種方法:

110951213.png

1.定義一個(gè)類繼承于Thread 實(shí)現(xiàn)run方法
首先看一下Thread的方法


image.png
class TestThread extends Thread{
    //實(shí)現(xiàn)run方法
    //方法里面就是需要具體執(zhí)行的代碼
    @Override
    public void run() {
        //System.out.println(Thread.currentThread().getName());
        for(int i=1;i<=100;i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (this != MyClass.tt1) {
                if (i == 10) {
                    try {
                        MyClass.tt1.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        super.run();
    }
}

然后再主函數(shù)中創(chuàng)建子線程

 static TestThread tt1;
    public static void main(String[] args) {
        //main方法里面執(zhí)行的代碼 是在主線程里面執(zhí)行的
        System.out.println(Thread.currentThread().getName());
        //創(chuàng)建對(duì)象
         TestThread tt=new TestThread();
         //設(shè)置線程名稱
        tt.setName("子線程1");
         //開啟任務(wù)
        tt.start();
        //創(chuàng)建對(duì)象
        tt1=new TestThread();
        //設(shè)置線程名稱
        tt1.setName("子線程2");
        //開啟任務(wù)
        tt1.start();

2.實(shí)現(xiàn)Runnable接口 實(shí)現(xiàn)run方法

  • a.創(chuàng)建任務(wù) 創(chuàng)建類實(shí)現(xiàn)Runnable接口
  • b.使用Thread為這個(gè)任務(wù)分配線程
  • c.開啟任務(wù) start
class TestTheard1 implements Runnable{
    public void run() {
        for (int i = 1; i <= 100; i++) {
             System.out.println(Thread.currentThread().getName()+" "+i);
        }
    }
}

這里有四種方式
第一種:

//1.接口 抽象方法
        //創(chuàng)建一個(gè)任務(wù):創(chuàng)建一個(gè)類來實(shí)現(xiàn)Runnable接口
        TestTheard1 TT=new TestTheard1();
        //使用Thread操作這個(gè)任務(wù)
        Thread T=new Thread(TT);
        T.setName("子線程1");
        T.start(); 

        Thread T1=new Thread(TT);
        T1.setName("子線程2");
        T1.start();

第二種:

 //這個(gè)任務(wù)只需要使用一次
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 100; i++) {
                    System.out.println(Thread.currentThread().getName()+" "+i);
                }
            }
        });
        t.setName("子線程1");
        t.start();

第三種:

//創(chuàng)建線程的同時(shí) 直接開啟線程本身的任務(wù)
        //不需要操作線程對(duì)象本身
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 100; i++) {
                         System.out.println(Thread.currentThread().getName()+" "+i);
                }
            }
        }).start();

第四種:

//使用Lambda表達(dá)式
        //不建議:閱讀性太差
        new Thread(()->{
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName()+" "+i);
            }
        }).start();

(3)線程安全

什么是線程安全:
按照自己的理解就是多個(gè)線程操作同一個(gè)資源澈圈,線程無法確定自己什么時(shí)候被阻塞彬檀,導(dǎo)致數(shù)據(jù)錯(cuò)誤。

怎末來解決線程安全問題:
就需要把每個(gè)線程分開來操作同一個(gè)資源瞬女,利用synchronized Lock;(加鎖 解鎖)窍帝,synchronized 同步的監(jiān)聽器 需要一把鎖,任何一個(gè)對(duì)象都有一把鎖(監(jiān)聽器)诽偷。如果多個(gè)線程操作統(tǒng)一的代碼塊

模板: synchronized(監(jiān)聽器/對(duì)象/鎖){需要同步的代碼}

1.同步代碼塊
- synchronized (監(jiān)聽器/對(duì)象/鎖){需要同步的代碼}

2.同步方法 同步監(jiān)聽器是當(dāng)前的對(duì)象本身
- 必須確保多個(gè)對(duì)象調(diào)用的同步方法是操作的是同一個(gè)對(duì)象
- public synchronized void test() 本質(zhì)就是同步代碼塊n
- 等價(jià)于synchronize(this) {test() ;}

實(shí)際應(yīng)用:
功能:火車站買票坤学,全國的買票系統(tǒng) 就一個(gè),重慶 上海

代碼:
首先我們要?jiǎng)?chuàng)建一個(gè)類繼承Runnable报慕,并實(shí)現(xiàn)run方法

synchronized鎖:

//用于買票的任務(wù)
class Ticket implements Runnable {
    //定義所有車票的數(shù)量
    public static int num = 100;
    String name;

    public Ticket(String name) {
        this.name = name;
    }

    @Override

    public void run() {
        synchronized (this) {
            test();
        }
    }

    public void test() {
        for (int i = 1; i <= 100; i++) {
            //判斷有沒有票
            if (num > 0) {
                System.out.println(name + " 出票:" + (101 - num));
                num--;
            } else {
                break;
            }
        }
    }
 }
}

然后在主函數(shù)中開始線程

Ticket ticket1=new Ticket("上海");
        Ticket ticket=new Ticket("重慶");
        Thread t1=new Thread(ticket);


        Thread t2=new Thread(ticket1);
        t2.start();
        t1.start();

交替進(jìn)行購票

ublic Ticket(String name) {
        this.name = name;
    }

    static final Object obj = new Object();
  public void run() {
        synchronized (this) {
            test();
        }
    }

    public void test() {
        for (int i = 1; i <= 100; i++) {
            //判斷有沒有票
            if (num > 0) {
                System.out.println(name + " 出票:" + (101 - num));
                num--;

      try {
                       //當(dāng)前線程等待
                           obj.notify()深浮;
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        //通知其他的線程執(zhí)行
                    }
                }else{
                break;
                }
          }
    }
}

第二種鎖:
可重入的鎖reentrantLock.
與上面的不同之處就是是實(shí)現(xiàn)aianrun方法不同

static ReentrantLock reentrantLock = new ReentrantLock();
    Condition condition = reentrantLock.newCondition();
 @Override
ublic void run() {
        for(int i=1;i<=100;i++){
            //判斷有沒有票
            reentrantLock.lock();
                //需要同步代碼塊
                if(num>0){
                System.out.println(name+" 出票:"+(101-num));
                num--;
                }else{
                break;
                }
            reentrantLock.unlock();
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市眠冈,隨后出現(xiàn)的幾起案子飞苇,更是在濱河造成了極大的恐慌,老刑警劉巖蜗顽,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件布卡,死亡現(xiàn)場離奇詭異,居然都是意外死亡雇盖,警方通過查閱死者的電腦和手機(jī)羽利,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刊懈,“玉大人,你說我怎么就攤上這事娃闲⌒檠矗” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵皇帮,是天一觀的道長卷哩。 經(jīng)常有香客問我,道長属拾,這世上最難降的妖魔是什么将谊? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮渐白,結(jié)果婚禮上尊浓,老公的妹妹穿的比我還像新娘。我一直安慰自己纯衍,他們只是感情好栋齿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般瓦堵。 火紅的嫁衣襯著肌膚如雪基协。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天菇用,我揣著相機(jī)與錄音澜驮,去河邊找鬼。 笑死惋鸥,一個(gè)胖子當(dāng)著我的面吹牛杂穷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播揩慕,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼亭畜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迎卤?” 一聲冷哼從身側(cè)響起拴鸵,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜗搔,沒想到半個(gè)月后劲藐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡樟凄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年聘芜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缝龄。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡汰现,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出叔壤,到底是詐尸還是另有隱情瞎饲,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布炼绘,位于F島的核電站嗅战,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏俺亮。R本人自食惡果不足惜驮捍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脚曾。 院中可真熱鬧东且,春花似錦、人聲如沸斟珊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至旨椒,卻和暖如春晓褪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背综慎。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工涣仿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人示惊。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓好港,卻偏偏與公主長得像,于是被迫代替她去往敵國和親米罚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子钧汹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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

  • 一、進(jìn)程和線程 進(jìn)程 進(jìn)程就是一個(gè)執(zhí)行中的程序?qū)嵗荚瘢總€(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間拔莱,一個(gè)進(jìn)程中可以有多個(gè)線程。...
    阿敏其人閱讀 2,611評(píng)論 0 13
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,952評(píng)論 1 18
  • 林炳文Evankaka原創(chuàng)作品隘竭。轉(zhuǎn)載自http://blog.csdn.net/evankaka 本文主要講了ja...
    ccq_inori閱讀 648評(píng)論 0 4
  • 本文主要講了java中多線程的使用方法塘秦、線程同步、線程數(shù)據(jù)傳遞动看、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法尊剔、概述等。 首先講...
    李欣陽閱讀 2,444評(píng)論 1 15
  • 本文出自 Eddy Wiki 菱皆,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,078評(píng)論 0 14