2019-08-18 Day17創(chuàng)建多線程

目的

了解多線程的概念 初步掌握多線程的使用方法

多線程

要了解多線程,首先要了解兩個(gè)概念 進(jìn)程和線程
進(jìn)程:
正在運(yùn)行的一個(gè)程序
系統(tǒng)會(huì)為這個(gè)進(jìn)程分配獨(dú)立的內(nèi)存空間
線程:
具體執(zhí)行任務(wù)的最小單位
一個(gè)進(jìn)程最少擁有一個(gè)線程(主線程 運(yùn)行起來就執(zhí)行的線程)
線程之間是共享內(nèi)存資源的
線程之間可以通信(通常在主線程和子線程之間)
每一個(gè)線程都有自己的運(yùn)行回路(生命周期)

所以說,線程是操作系統(tǒng)運(yùn)行的基本單位,它被封裝在進(jìn)程中,一個(gè)進(jìn)程可以包含多個(gè)線程。

為什么要使用多線程

如果在主線程中存在有比較耗時(shí)的操作,下載視頻上傳文件,這些操作會(huì)阻塞主線程,后面的任務(wù)必須等這些任務(wù)執(zhí)行完畢,之后才能執(zhí)行,用戶體驗(yàn)比較差,為了不阻塞主線程,需要將耗時(shí)的任務(wù)放在子線程中去處理,也就形成了多線程

線程的生命周期

NEW 新建 線程剛剛被創(chuàng)造好
RUNNABLE: 就緒狀態(tài)
BLOCKED 阻塞狀態(tài)
WAITING 等待
TERMINATED 終止

如圖:


線程狀態(tài).png

創(chuàng)建線程和啟動(dòng)

(1)繼承Thread類創(chuàng)建線程類,步驟如下
1.定義一個(gè)繼承Thread類的子類,并重寫該類的run()方法;
2.創(chuàng)建Thread子類的實(shí)例,即創(chuàng)建了線程對(duì)象;
3.調(diào)用該線程對(duì)象的start()方法啟動(dòng)線程。

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

        TestThread tt2 = new TestThread();
        //設(shè)置線程的名稱
        tt2.setName("子線程2");
        //開啟任務(wù)
        tt2.start();}
}
class TestThread extends Thread{
    //實(shí)現(xiàn)run方法
    //方法里面就是具體需要執(zhí)行的代碼

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        for (int i = 0; i < 100; i++) {

            System.out.println("name:"+name+" "+(i+1));

        }
        super.run();
    }
}

(2.)實(shí)現(xiàn)Runnable接口創(chuàng)建線程類,步驟如下
1.定義Runnable接口的實(shí)現(xiàn)類,并重寫該接口的run()方法;
2.創(chuàng)建Runnable實(shí)現(xiàn)類的實(shí)例,并以此實(shí)例作為Thread的target對(duì)象,即該Thread對(duì)象才是真正的線程對(duì)象。

public class MyClass {
    public static void main(String[] args){

PXDThread pt = new PXDThread();

      //使用Thread操作這個(gè)任務(wù)
      Thread t = new Thread(pt);
      t.setName("子線程1");
      t.start();

      Thread t2 = new Thread(pt);
        t2.setName("子線程2");
        t2.start();
}
}
class PXDThread implements   Runnable{

    public void run() {
        for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+":"+(i+1));
        }

    }
}

線程安全

線程安全就是多線程訪問時(shí),采用了加鎖機(jī)制,當(dāng)一個(gè)線程訪問該類的某個(gè)數(shù)據(jù)時(shí),進(jìn)行保護(hù),其他線程不能進(jìn)行訪問直到該線程讀取完,其他線程才可使用。不會(huì)出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染。比如說在買票系統(tǒng)中,如果沒有采用加鎖機(jī)制,就會(huì)導(dǎo)致,一張票被兩個(gè)人所購(gòu)買的情況。

如何實(shí)現(xiàn)線程安全

實(shí)現(xiàn)線程安全,主要通過,synchronized 或者LOCK 進(jìn)行加鎖解鎖,主要有兩種方法
1.同步代碼塊
2.同步方法

public class MyClass {
    public static void main(String[] args){
 Ticket ticketCQ = new Ticket("重慶");
     Thread t1 = new Thread(ticketCQ);
     t1.start();

        Ticket ticketSH = new Ticket("上海");
        Thread t2 = new Thread(ticketSH);
        t2.start();
    }
}//用于賣票的任務(wù)
class Ticket implements Runnable{
    public static  int num = 100;
    String name;

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


    }
    static  final Object obj = new Object();
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            //判斷有沒有票
            synchronized (obj) {
                    //需要同步的代碼

                if (num > 0) {

                    System.out.println(name + "出票:" + (101 - num));
                    num--;
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        //通知其他線程執(zhí)行
                        notify();
                    }
                } else {
                    break;
                }
            }
        }

這里我們用synchronized同步代碼塊的方法 進(jìn)行了加鎖解鎖,但實(shí)際上同步方法,本質(zhì)上也是利用了同步代碼塊,只是同步的監(jiān)聽器是當(dāng)前對(duì)象本身,容易出錯(cuò),所以必須確保多個(gè)對(duì)象調(diào)用的同步方法是操作的同一個(gè)對(duì)象。

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

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

  • ??一個(gè)任務(wù)通常就是一個(gè)程序,每個(gè)運(yùn)行中的程序就是一個(gè)進(jìn)程。當(dāng)一個(gè)程序運(yùn)行時(shí),內(nèi)部可能包含了多個(gè)順序執(zhí)行流,每個(gè)順...
    OmaiMoon閱讀 1,804評(píng)論 0 12
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 3,107評(píng)論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,597評(píng)論 1 15
  • Java 多線程 線程和進(jìn)程的區(qū)別 線程和進(jìn)程的本質(zhì):由CPU進(jìn)行調(diào)度的并發(fā)式執(zhí)行任務(wù),多個(gè)任務(wù)被快速輪換執(zhí)行,使...
    安安zoe閱讀 2,260評(píng)論 1 18
  • “生于1959的凱文-史派西,父親是個(gè)專業(yè)作家,母親是個(gè)秘書。幼時(shí)被送于洛杉磯諾斯雷治軍校,因斗毆事件遭逐出,后轉(zhuǎn)...
    Yve鹽閱讀 2,024評(píng)論 1 3

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