Java多線程

學(xué)習(xí)java多線程的一下知識的總結(jié),寫在這里,防止自己遺忘,也是為了復(fù)習(xí)。

JVM的啟動是單線程還是多線程的??

JVM啟動的時候不僅僅啟動了主線程,而且啟動了垃圾回收線程,所以JVM的啟動是多線程的。

如何實現(xiàn)多線程?

兩種方式:

  1. 繼承Thread類
    1. 自定義MyThread類繼承了Thread類
    2. 重寫MyThread類中的run()方法
    3. 創(chuàng)建MyThread對象
    4. 啟動線程對象
  1. 實現(xiàn)Runable接口
    1. 自定義MyRunnable類實現(xiàn)了Runnable接口
    2. 重寫MyRunnable類中的run()方法
    3. 創(chuàng)建MyRunnable對象
    4. 創(chuàng)建Thread對象,把MyRunnable對象對象作為構(gòu)造函數(shù)的入?yún)?/li>

對于繼承Thread來說,是通過重寫了run方法來實現(xiàn)的,因為一個類的代碼并不是都需要多線程執(zhí)行的,只會執(zhí)行run方法里面的代碼。

為什么有兩張方式來實現(xiàn)多線程???

  1. 由于Java只支持單繼承,避免單繼承導(dǎo)致的多線程的局限性
  2. 適合多個相同程序的代碼去處理同一個資源,吧線程相同程序的代碼,數(shù)據(jù)有效分離,體現(xiàn)了Java面向?qū)ο蟮脑O(shè)計思想。

如果重復(fù)調(diào)用run會發(fā)現(xiàn),還是單線程執(zhí)行,原因是run方法它是單行程的。

可以通過start方法來執(zhí)行,如果調(diào)用兩次start方法,并不能進行多線程操作,由于已經(jīng)執(zhí)行了start方法,再次執(zhí)行start會報錯,,報錯信息如下:

連續(xù)執(zhí)行對象的線程start方法報錯.png

所以可以實例化兩個對象,分別啟動對象的線程,會發(fā)現(xiàn)他們兩個確實是多線程執(zhí)行的??吹絻蓚€for循環(huán)是同時執(zhí)行的,并沒有順序執(zhí)行。

代碼示例:

package com.aircjm.thread;

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
        }
    }
}

package com.aircjm.thread;

public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();

        //由于run()方法時單線程的,所以還是按照單線程執(zhí)行,一個run()執(zhí)行完了,另一個run()才會執(zhí)行
        //myThread.run();
        //myThread.run();

        //可以通過start()方法來啟動線程
        //兩者之間的區(qū)別,start是使該線程開始執(zhí)行,JVM調(diào)用該線程的run()方法
        //myThread.start();
        //myThread.start();

        MyThread myThread1 = new MyThread();
        MyThread myThread2 = new MyThread();

        myThread1.start();
        myThread2.start();


    }
}

如何獲取繼承Thread的線程對象的名稱

public final String getName() //獲取線程的名詞

線程控制的幾個方法:

休眠線程:
public static void sleep(long millis) throws InterruptedException

在指定的毫秒數(shù)內(nèi)讓當前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計時器和調(diào)度程序精度和準確性的影響。該線程不丟失任何監(jiān)視器的所屬權(quán)。
啟動線程:
start

public void start()
使該線程開始執(zhí)行;Java 虛擬機調(diào)用該線程的 run 方法。
結(jié)果是兩個線程并發(fā)地運行;當前線程(從調(diào)用返回給 start 方法)和另一個線程(執(zhí)行其 run 方法)。

多次啟動一個線程是非法的。特別是當線程已經(jīng)結(jié)束執(zhí)行后,不能再重新啟動。

拋出:
IllegalThreadStateException - 如果線程已經(jīng)啟動。
另請參見:
run(), stop()
run

public void run()
如果該線程是使用獨立的 Runnable 運行對象構(gòu)造的,則調(diào)用該 Runnable 對象的 run 方法;否則,該方法不執(zhí)行任何操作并返回。
Thread 的子類應(yīng)該重寫該方法。

加入線程:

禮讓線程:

守護線程:

中斷線程:

啟動線程用的是哪個方法?

start()

run()和start()方法的區(qū)別?

  1. run直接調(diào)用,調(diào)用的是普通方法
  2. start()方法,是啟動線程,然后JVM調(diào)用了run()方法

如何讓線程安全??

給需要線程安全的地方進行加鎖

public class SellTicket implements Runnable {
    private Integer ticketNum = 100;
    public void run() {
        while (true){
            synchronized (ticketNum){
                if (ticketNum>0){
                    System.out.println("now is sell "+ ticketNum-- +" ticket");
                }
            }
        }
    }
}

加鎖的方式有多種,可以給代碼塊加鎖(鎖對象是任意對象),可以給方法加鎖(鎖對象是this),也可以給靜態(tài)方法加鎖(鎖對象是字節(jié)碼文件)

學(xué)習(xí)到的線程安全的對象有:

StringBuffer stringBuffer = new StringBuffer();
Vector<String> vector = new Vector<String>();
Hashtable<String, Object> hashTable = new Hashtable<String, Object>();
// 即使線程安全但是也不推薦使用
Vector<String> vector = new Vector<String>();
Hashtable<String, Object> hashTable = new Hashtable<String, Object>();

// 如何使用線程安全的List呢??
List<String> list = Collections.synchronizedList(new ArrayList<String>()); // 線程安全
List<String> list1 = new ArrayList<String>(); //線程不安全

通過靜態(tài)方法獲取到線程安全的List集合

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 這篇文章中,我不會說多線程是什么、線程和進程的區(qū)別、多線程有什么用,當然我也不會說什么是串行、什么是并行等問...
    hashakey閱讀 366評論 0 0
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,041評論 0 9
  • Java Thread 總結(jié) 【顯示目錄】 ?線程的概述(Introduction) 線程是一個程序的多個執(zhí)行路徑...
    夏6閱讀 415評論 0 0
  • 1.要做一個盡可能流暢的ListView,你平時在工作中如何進行優(yōu)化的? ①Item布局,層級越少越好,使用hie...
    fozero閱讀 872評論 0 0

友情鏈接更多精彩內(nèi)容