線程

1 線程概述

  • 線程的核心問題是線程提供了并行解決方案

2 線程的相關(guān)概念

2.1 進(jìn)程

進(jìn)程(Process)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)動(dòng)活動(dòng),是操作系統(tǒng)進(jìn)行資源分配與調(diào)度的基本單位??梢园堰M(jìn)程簡(jiǎn)單的理解為正在操作系統(tǒng)中運(yùn)行的一個(gè)程序

2.2 線程

1 線程(Thread)是進(jìn)程的一個(gè)執(zhí)行單元。一個(gè)線程就是進(jìn)程中一個(gè)單一順序的控制流,是進(jìn)程的一個(gè)執(zhí)行分支。
2 進(jìn)程是線程的容器,一個(gè)進(jìn)程至少有一個(gè)線程,當(dāng)一個(gè)進(jìn)程中沒有線程時(shí),這個(gè)進(jìn)程就結(jié)束了。
3 在操作系統(tǒng)中是以進(jìn)程為單位分配資源。每個(gè)線程都有各自的線程棧,自己的寄存器環(huán)境,自己的線程本地存儲(chǔ)。
4 主線程與子線程:JVM啟動(dòng)時(shí)會(huì)創(chuàng)建一個(gè)主線程,該主線程負(fù)責(zé)執(zhí)行main方法。主線程就是運(yùn)行main方法的線程。Java中的線程是不孤立的,線程之間存在一些聯(lián)系。如果A線程中創(chuàng)建了B線程,稱B線程為A線程的子線程,相應(yīng)的A線程是B線程的父線程。

2.3 串行、并發(fā)、并行

2.3.1串行(Sequential)

一個(gè)挨著一個(gè)順序執(zhí)行,前面的執(zhí)行完畢后,再執(zhí)行后面的。效率低。

2.3.2 并發(fā)(Concurrent)

一段時(shí)間內(nèi)多個(gè)任務(wù)都在運(yùn)行。效率高。

2.3.3 并行(Parallel)

多個(gè)任務(wù)同時(shí)開始,是并發(fā)的特殊情況。效率高。
如下圖:


image.png

3 創(chuàng)建線程的方法

  • 方法1:繼承Thread類
  • 方法2:實(shí)現(xiàn)Runnable接口
  • 方法3:實(shí)現(xiàn)Callable接口
  • 方法4:使用線程池創(chuàng)建線程

3.1 繼承Thread類創(chuàng)建線程

//1:定義類繼承 Thread
public class Thread01 extends Thread{
    //2:重寫 Thread 父類中的 run()
    @Override
    public void run() {
        System.out.println("子線程");
    }

    public static void main(String[] args) {
        //3)創(chuàng)建子線程對(duì)象
        Thread01 t=new Thread01();
        //4)啟動(dòng)線程
        t.start();
        System.out.println("主線程");
    }
}

運(yùn)行結(jié)果:
主線程
子線程
代碼分析:

  • 調(diào)用線程的start()方法來啟動(dòng)線程。啟動(dòng)線程的實(shí)質(zhì)就是請(qǐng)求JVM運(yùn)行相應(yīng)的線程,這個(gè)線程具體什么時(shí)候運(yùn)行由線程調(diào)度器(Scheduler)決定。
  • start()方法的作用:?jiǎn)?dòng)子線程,啟動(dòng)成功的線程會(huì)自動(dòng)調(diào)用run()方法。
  • 如果開啟了多個(gè)線程,start()調(diào)用的順序并不一定就是線程啟動(dòng)的順序,多線程運(yùn)行結(jié)果與代碼執(zhí)行順序或調(diào)用順序無關(guān)。線程調(diào)用具有隨機(jī)性

3.2 實(shí)現(xiàn)Runnable接口創(chuàng)建線程

如果線程類已經(jīng)有父類,就不能使用繼承Thread類來實(shí)現(xiàn)線程,此時(shí)可以實(shí)現(xiàn)Runnable接口來創(chuàng)建線程。

public class Thread03_1 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i <100 ; i++) {
            System.out.println("sub "+i);
        }
    }

    public static void main(String[] args) {
        Thread03_1 thread03_1 = new Thread03_1();
        Thread thread = new Thread(thread03_1);
        thread.start();
        for (int i = 0; i <100 ; i++) {
            System.out.println("main "+i);
        }
    }
}

3.3 實(shí)現(xiàn)Callable接口創(chuàng)建線程

Callable接口內(nèi)只有一個(gè)call方法,所以是函數(shù)式接口,能返回線程執(zhí)行結(jié)果,要拋異常,結(jié)合FutureTask類獲取線程的返回值

class MyThread implements Callable<String>{

    @Override
    public String call() throws Exception {
        for (int i = 0; i <5 ; i++) {
            System.out.println("call i="+i);
        }
        return "callable";
    }
}
public class CallableDemo {
    public static void main(String[] args) {
        //創(chuàng)建線程對(duì)象
        MyThread myThread=new MyThread();
        //將線程對(duì)象包裝到futureTask中,線程返回Stirng類型的值
        FutureTask<String> futureTask=new FutureTask<>(myThread);
        Thread thread=new Thread(futureTask);
        //啟動(dòng)線程
        thread.start();

        String result= null;
        try {
            //獲取線程返回結(jié)果
            result = (String) futureTask.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //輸出返回結(jié)果
        System.out.println(result);
    }
}

運(yùn)行結(jié)果:
call i=0
call i=1
call i=2
call i=3
call i=4
callable

?著作權(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)容

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