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

資訊專欄INFORMATION COLUMN

慕課網(wǎng)_《細(xì)說(shuō)多線程之Thread VS Runnable》學(xué)習(xí)總結(jié)

netScorpion / 2244人閱讀

摘要:時(shí)間年月日星期六說(shuō)明本文部分內(nèi)容均來(lái)自慕課網(wǎng)。慕課網(wǎng)教學(xué)源碼無(wú)學(xué)習(xí)源碼第一章課前準(zhǔn)備前言課程說(shuō)明比較和這兩種線程創(chuàng)建的方式,需要知道和的基本創(chuàng)建方式。一旦主線程獲取到了用戶的輸入,這時(shí)候,阻塞就會(huì)解除掉,主線程繼續(xù)運(yùn)行,直到結(jié)束。

時(shí)間:2017年07月08日星期六
說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com
教學(xué)源碼:無(wú)
學(xué)習(xí)源碼:https://github.com/zccodere/s...

第一章:課前準(zhǔn)備 1-1 前言

課程說(shuō)明

比較Thread和Runnable這兩種線程創(chuàng)建的方式,需要知道Thread和Runnable的基本創(chuàng)建方式。

課程目標(biāo)和學(xué)習(xí)內(nèi)容

線程創(chuàng)建的兩種方式比較
線程的生命周期
線程的守護(hù)神:守護(hù)線程
第二章:Thread VS Runnable 2-1 回顧線程創(chuàng)建的兩種方式

方式一:繼承Thread類

方式二:實(shí)現(xiàn)Runnable接口

線程創(chuàng)建的兩種方式

2-2 應(yīng)用Thread模擬賣票

兩種方式的比較

Runnable方式可以避免Thread方式由于Java單繼承特性帶來(lái)的缺陷
Runnable的代碼可以被多個(gè)線程(Thread實(shí)例)共享,適合于多個(gè)線程處理同一個(gè)資源的情況

案例:模擬買票

代碼演示

1.編寫(xiě)MyThread類

package com.myimooc.ticketsthread;

/**
 * 使用 Thread 創(chuàng)建線程
 * @author ZhangCheng on 2017-07-08
 *
 */
public class MyThread extends Thread {
    
    /** 一共有5張火車票 */
    private int ticketsCont = 5;
    /** 窗口,也即是線程的名字 */
    private String name;
    
    public MyThread(String name){
        this.name = name;
    }
    
    // 寫(xiě)買票邏輯
    @Override
    public void run() {
        while(ticketsCont > 0 ){
            // 如果還有票,就賣掉一張
            ticketsCont--;
            System.out.println(name + "賣了1張票,剩余票數(shù)為:"+ticketsCont);
        }
    }
}

2.編寫(xiě)TicketsThread類

package com.myimooc.ticketsthread;

/**
 * 主類-啟動(dòng)線程類
 * @author ZhangCheng on 2017-07-08
 *
 */
public class TicketsThread {
    
    public static void main(String[] args) {
        
        // 創(chuàng)建三個(gè)線程,模擬三個(gè)窗口賣票
        MyThread mt1 = new MyThread("窗口1");
        MyThread mt2 = new MyThread("窗口2");
        MyThread mt3 = new MyThread("窗口3");
        
        // 啟動(dòng)這三個(gè)線程,即窗口開(kāi)始賣票
        mt1.start();
        mt2.start();
        mt3.start();
    }
    
}

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

總共有5張票,但是三個(gè)窗口加在一起賣了15張票。造成有些人買了票,上不了車,這種情況不是我們?cè)敢饪吹降?。具體原因,寫(xiě)完Runnable后,會(huì)講解。

2-3 應(yīng)用Runnable模擬賣票

代碼演示

1.編寫(xiě)MyThread類

package com.myimooc.ticketsrunnable;

/**
 * 使用 Runnable 創(chuàng)建線程
 * @author ZhangCheng on 2017-07-08
 *
 */
public class MyThread implements Runnable {
    
    /** 一共有5張火車票 */
    private int ticketsCont = 5;
    
    // 寫(xiě)買票邏輯
    @Override
    public void run() {
        while(ticketsCont > 0 ){
            // 如果還有票,就賣掉一張
            ticketsCont--;
            System.out.println(Thread.currentThread().getName() + "賣了1張票,剩余票數(shù)為:"+ticketsCont);
        }
    }
}

2.編寫(xiě)TicketsRunnable類

package com.myimooc.ticketsrunnable;

/**
 * 主類-啟動(dòng)線程類
 * @author ZhangCheng on 2017-07-08
 *
 */
public class TicketsRunnable {
    
    public static void main(String[] args) {
        
        MyThread mt = new MyThread();
        
        // 創(chuàng)建三個(gè)線程,模擬三個(gè)窗口賣票
        Thread th1 = new Thread(mt,"窗口1");
        Thread th2 = new Thread(mt,"窗口2");
        Thread th3 = new Thread(mt,"窗口3");
        
        // 啟動(dòng)這三個(gè)線程,即窗口開(kāi)始賣票
        th1.start();
        th2.start();
        th3.start();
        
    }
    
}

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

2-4 應(yīng)用揭秘

兩種方式的區(qū)別

第三章:線程的生命周期和守護(hù)線程 3-1 線程的生命周期

線程的生命周期

創(chuàng)建

新建一個(gè)線程對(duì)象,如Threaf thd = new Thread()

就緒

創(chuàng)建了線程對(duì)象后,調(diào)用了線程的start()方法(注意:此時(shí)線程只是進(jìn)入了線程隊(duì)列,等待獲取CPU服務(wù),具備了運(yùn)行的條件,但并不一定已經(jīng)開(kāi)始運(yùn)行了)

運(yùn)行

處于就緒狀態(tài)的線程,一旦獲取了CPU資源,便進(jìn)入到運(yùn)行狀態(tài),開(kāi)始執(zhí)行run()方法里面的邏輯

終止

線程的run()方法執(zhí)行完畢,或者線程調(diào)用了stop()方法,線程便進(jìn)入終止?fàn)顟B(tài)    

阻塞

一個(gè)正在執(zhí)行的線程在某些情況下,由于某種原因而暫時(shí)讓出了CPU資源,暫停了自己的執(zhí)行,便進(jìn)入了阻塞狀態(tài),如調(diào)用了sleep()方法

阻塞狀態(tài)示意圖

3-2 守護(hù)線程理論知識(shí)

Java線程有兩類

用戶線程:運(yùn)行在前臺(tái),執(zhí)行具體的任務(wù)
    程序的主線程、連接網(wǎng)絡(luò)的子線程等都是用戶線程
守護(hù)線程:運(yùn)行在后臺(tái),為其他前臺(tái)線程服務(wù)
    特點(diǎn):一旦所有用戶線程都結(jié)束運(yùn)行,守護(hù)線程會(huì)隨JVM一起結(jié)束工作
    應(yīng)用:數(shù)據(jù)庫(kù)連接池中的監(jiān)測(cè)線程、JVM虛擬機(jī)啟動(dòng)后的監(jiān)測(cè)線程
    最常見(jiàn)的守護(hù)線程:垃圾回收線程

如何設(shè)置守護(hù)線程

可以通過(guò)調(diào)用Thread類的setDaemon(true)方法來(lái)設(shè)置當(dāng)前的線程為守護(hù)線程

注意事項(xiàng)

setDaemon(true)必須在start()方法之前調(diào)用,否則會(huì)拋出IllegalThreadStateException異常
在守護(hù)線程中產(chǎn)生的新線程也是守護(hù)線程
不是所有的任務(wù)都可以分配給守護(hù)線程來(lái)執(zhí)行,比如讀寫(xiě)操作或者計(jì)算邏輯
3-3 守護(hù)線程代碼示例

模擬場(chǎng)景示意圖

模擬場(chǎng)景說(shuō)明

一共有兩個(gè)線程,一個(gè)主線程,一個(gè)守護(hù)線程。守護(hù)線程會(huì)在很長(zhǎng)的時(shí)間內(nèi)不停的往文件中寫(xiě)數(shù)據(jù),主線程會(huì)阻塞等待來(lái)自鍵盤(pán)的輸入。一旦主線程獲取到了用戶的輸入,這時(shí)候,阻塞就會(huì)解除掉,主線程繼續(xù)運(yùn)行,直到結(jié)束。而一旦主線程結(jié)束,用戶線程就沒(méi)有了。這時(shí)候即使數(shù)據(jù)還沒(méi)有寫(xiě)完,守護(hù)線程也會(huì)隨虛擬機(jī)一起結(jié)束運(yùn)行。

代碼演示

1.編寫(xiě)DaemonThread類

package com.myimooc.daemonthread;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

/**
 * 守護(hù)線程。使用 Runnable 創(chuàng)建線程
 * @author ZhangCheng on 2017-07-08
 *
 */
public class DaemonThread implements Runnable {

    @Override
    public void run() {
        System.out.println("進(jìn)入守護(hù)線程" + Thread.currentThread().getName());
        
        try {
            writeToFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        System.out.println("退出守護(hù)線程" + Thread.currentThread().getName());
    }

    private void writeToFile() throws Exception{
        
        File fileName = new File("d:" + File.separator + "daemon.txt");
        // 向文件中追加數(shù)據(jù)
        OutputStream os = new FileOutputStream(fileName,true);
        int count = 0;
        while(count < 999){
            os.write(("
word" + count).getBytes());
            System.out.println("守護(hù)線程" + Thread.currentThread().getName() 
                + "向文件中寫(xiě)入了word" + count);
            count++;
            // 線程休眠1秒
            Thread.sleep(1000);
        }
        os.close();
    }
}

2.編寫(xiě)DaemonThreadDemo類

package com.myimooc.daemonthread;

import java.util.Scanner;

/**
 * 主線程
 * @author ZhangCheng on 2017-07-08
 *
 */
public class DaemonThreadDemo {

    public static void main(String[] args) {
        
        System.out.println("進(jìn)入主線程" + Thread.currentThread().getName());
        
        DaemonThread daemonThread = new DaemonThread();
        Thread thread = new Thread(daemonThread);
        thread.setDaemon(true);
        thread.start();
        
        Scanner sc = new Scanner(System.in);
        sc.next();
        sc.close();
        
        System.out.println("退出主線程" + Thread.currentThread().getName());
        
    }

}
3-4 使用jstack生成線程快照

常用查看線程工具

jstack

作用:生成JVM當(dāng)前時(shí)刻線程的快照(threaddump,即當(dāng)前進(jìn)程中所有線程的信息)
目的:幫助定位程序問(wèn)題出現(xiàn)的原因,如長(zhǎng)時(shí)間停頓、CPU占用率過(guò)高等

使用命令

jstack -l PID
生成線程快照

快照案例

2017-07-08 23:49:46
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode):

"Thread-0" #10 daemon prio=5 os_prio=0 tid=0x000000001d209800 nid=0x2e00 waiting on condition [0x000000001dd2f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at com.myimooc.daemonthread.DaemonThread.writeToFile(DaemonThread.java:39)
        at com.myimooc.daemonthread.DaemonThread.run(DaemonThread.java:19)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001d1b9800 nid=0x2480 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000001d13b000 nid=0x2078 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000001be2d800 nid=0x24f4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001bddf000 nid=0x2f64 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001bdde000 nid=0x1c1c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001bdc8800 nid=0x247c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001bdba800 nid=0x1f10 in Object.wait() [0x000000001d12f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076b108ee0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x000000076b108ee0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

   Locked ownable synchronizers:
        - None

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000027a2800 nid=0x2214 in Object.wait() [0x000000001d02f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076b106b50> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x000000076b106b50> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

   Locked ownable synchronizers:
        - None

"main" #1 prio=5 os_prio=0 tid=0x000000000099d800 nid=0xf2c runnable [0x000000000228e000]
   java.lang.Thread.State: RUNNABLE
        at java.io.FileInputStream.readBytes(Native Method)
        at java.io.FileInputStream.read(FileInputStream.java:255)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
        - locked <0x000000076b159560> (a java.io.BufferedInputStream)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        - locked <0x000000076b1b9ce8> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.Reader.read(Reader.java:100)
        at java.util.Scanner.readInput(Scanner.java:804)
        at java.util.Scanner.next(Scanner.java:1369)
        at com.myimooc.daemonthread.DaemonThreadDemo.main(DaemonThreadDemo.java:22)

   Locked ownable synchronizers:
        - None

"VM Thread" os_prio=2 tid=0x000000001bd98000 nid=0x2998 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000026c6800 nid=0x11b0 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000026c8000 nid=0x26a4 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000026c9800 nid=0x2d6c runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000000026cb000 nid=0xab0 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x000000001d1f3000 nid=0x2b08 waiting on condition

JNI global references: 6

總結(jié)

1.如果有daemon標(biāo)記,則當(dāng)前線程為守護(hù)線程
2.通過(guò)查看線程狀態(tài)(java.lang.Thread.State: TIMED_WAITING (sleeping))
    可以幫助我們定位到導(dǎo)致程序出現(xiàn)死鎖,或者是阻塞問(wèn)題的原因
3.tid和nid字段可以幫助我們找到CPU占有率很高的線程
第四章:課程總結(jié) 4-1 課程總結(jié)

課程總結(jié)

線程創(chuàng)建的兩種方式回顧
線程創(chuàng)建的兩種方式比較
線程的聲明周期
守護(hù)線程
jsrack生成線程快照

建議

多使用Runnable這種方式創(chuàng)建線程

補(bǔ)充

1.程序中的同一資源指的是同一個(gè)Runnable對(duì)象
2.安全的賣票程序中需要加入同步(Synchronized)

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

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

相關(guān)文章

  • 課網(wǎng)_細(xì)說(shuō)Java線程內(nèi)存可見(jiàn)性》學(xué)習(xí)總結(jié)

    時(shí)間:2017年07月09日星期日說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:無(wú)學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程簡(jiǎn)介 1-1 課程簡(jiǎn)介 課程目標(biāo)和學(xué)習(xí)內(nèi)容 共享變量在線程間的可見(jiàn)性 synchronized實(shí)現(xiàn)可見(jiàn)性 volatile實(shí)現(xiàn)可見(jiàn)性 指令重排序 as-if-seria...

    wupengyu 評(píng)論0 收藏0
  • 課網(wǎng)_《使用Google Guice實(shí)現(xiàn)依賴注入》學(xué)習(xí)總結(jié)

    摘要:時(shí)間年月日星期六說(shuō)明本文部分內(nèi)容均來(lái)自慕課網(wǎng)。慕課網(wǎng)教學(xué)源碼學(xué)習(xí)源碼第一章課程介紹課程簡(jiǎn)介是啥讀音是輕量級(jí)的依賴注入框架說(shuō)明一個(gè)的框架需要有基礎(chǔ)什么是剝離注入輕量級(jí)代碼少易維護(hù)性能優(yōu)異,跟比較。 時(shí)間:2017年10月14日星期六說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com 教學(xué)源碼:https://github.com/zccodere/s......

    2450184176 評(píng)論0 收藏0
  • 課網(wǎng)_《Spring Boot熱部署》學(xué)習(xí)總結(jié)

    時(shí)間:2017年12月01日星期五說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com 教學(xué)源碼:無(wú) 學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 熱部署的使用場(chǎng)景 本地調(diào)式 線上發(fā)布 熱部署的使用優(yōu)點(diǎn) 無(wú)論本地還是線上,都適用 無(wú)需重啟服務(wù)器:提高開(kāi)發(fā)、調(diào)式效率、提升發(fā)布、運(yùn)維效率、降低運(yùn)維成本 前置...

    Channe 評(píng)論0 收藏0
  • 課網(wǎng)_《Java定時(shí)任務(wù)調(diào)度工具詳解Timer篇》學(xué)習(xí)總結(jié)

    時(shí)間:2017年05月24日星期三說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:無(wú)個(gè)人學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 什么是定時(shí)任務(wù)調(diào)度 基于給定的時(shí)間點(diǎn),給定的時(shí)間間隔或者給定的執(zhí)行次數(shù)自動(dòng)執(zhí)行的任務(wù) 在Java中的定時(shí)調(diào)度工具 Timer:小弟,能實(shí)現(xiàn)日常60%的定...

    wind5o 評(píng)論0 收藏0
  • 《Java編程方法論:響應(yīng)式RxJava與代碼設(shè)計(jì)實(shí)戰(zhàn)》序

    摘要:原文鏈接編程方法論響應(yīng)式與代碼設(shè)計(jì)實(shí)戰(zhàn)序,來(lái)自于微信公眾號(hào)次靈均閣正文內(nèi)容在一月的架構(gòu)和設(shè)計(jì)趨勢(shì)報(bào)告中,響應(yīng)式編程和函數(shù)式仍舊編列在第一季度的早期采納者中。 原文鏈接:《Java編程方法論:響應(yīng)式RxJava與代碼設(shè)計(jì)實(shí)戰(zhàn)》序,來(lái)自于微信公眾號(hào):次靈均閣 正文內(nèi)容 在《2019 一月的InfoQ 架構(gòu)和設(shè)計(jì)趨勢(shì)報(bào)告》1中,響應(yīng)式編程(Reactive Programming)和函數(shù)式...

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

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

0條評(píng)論

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