欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java超詳細講解多線程中的Process與Thread

 更新時間:2022年05月05日 08:42:04   作者:留在夢里  
進程process:在一定的環(huán)境下,把靜態(tài)的程序代碼運行起來,通過使用不同的資源,來完成一定的任務(wù);線程thread:是程序中一個單一的順序控制流程。在單個進程中同時運行多個線程完成不同的工作,稱為多線程

進程和線程的關(guān)系

?在操作系統(tǒng)中運行的程序就是進程,比如說QQ,播放器,游戲等等…程序是指令和數(shù)據(jù)的有序集合,其本身沒有任何運行的含義,是一個靜態(tài)的概念.

?進程和線程都是為了處理并發(fā)編程這樣的場景,但是進程有問題,頻繁拆功創(chuàng)建和釋放資源的時候效率低,相比之下,線程更輕量,創(chuàng)建和釋放效率更高.

?進程具有獨立性,每個進程有各自獨立的虛擬地址空間,一個進程掛了,不會影響其他進程,同一個進程中的多個線程,共用同一個內(nèi)存空間,一個線程掛了,可能影響其他的線程,甚至導(dǎo)致整個進程崩潰…

?而進程則是執(zhí)行程序的一次執(zhí)行過程,他是一個動態(tài)的概念,是系統(tǒng)資源分配的單位

?通常在一個進程中可以包含多個線程(如果把進程想象成一個工廠,那么線程就是工廠里的生產(chǎn)線,一個工廠里面面可以有一個生產(chǎn)線,也可以有多個生產(chǎn)線),當(dāng)然一個進程中至少一個線程,不然沒有存在的意義,線程是CPU調(diào)度和執(zhí)行的單位.

?真正的多線程是指有多個CPU,即多核.

?線程就是獨立執(zhí)行的路徑

?在程序執(zhí)行時,即使沒有自己創(chuàng)建線程,后臺也會有多個線程,如主線程,GC線程.

?每個線程在自己的工作內(nèi)存交互,內(nèi)存操控不當(dāng)會造成數(shù)據(jù)不一致.

操作系統(tǒng)是如何管理進程的

1.先描述一個進程.(明確除一個進程上面的一些相關(guān)屬性)

2.在組織若干個進程.(使用一些數(shù)據(jù)結(jié)構(gòu),把很多描述進程的信息放到一起,方便進行增刪查改,典型的實現(xiàn),就是使用雙向鏈表把每個進程的PCB串起來).

并行和并發(fā)

并行:微觀上,兩個CPU核心,同步你是執(zhí)行兩個任務(wù)的代碼.

并發(fā):微觀上,一個CPU核心,先執(zhí)行一會任務(wù)1,在執(zhí)行一會任務(wù)2,在執(zhí)行一會兒任務(wù)3,只要切換足夠快,宏觀上看起來,就好像很多任務(wù)同時執(zhí)行一樣,

并發(fā)和并行,只有在微觀上可以區(qū)分,宏觀上區(qū)分不了,微觀上這里的區(qū)分都是都是操作西歐統(tǒng)自動調(diào)度的結(jié)果.正因為供觀賞區(qū)分不了并行和并發(fā),在寫代碼的時候不去區(qū)分,只是在研究操作系統(tǒng)進程調(diào)度的時候稍做區(qū)分,其它場景基本都是使用并發(fā)作為一個統(tǒng)稱來代替.

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

方法一: 通過Thread類創(chuàng)建線程,這是最簡單的方法,創(chuàng)建子類,繼承Thread類,并重寫run方法.

package thread;
class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("hello thread");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
    }
}

方法二:

import java.util.Scanner;

class MyThread2 extends Thread{
    @Override
    public void run() {
        System.out.println("hello thread!");
        try {
            Thread.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
public class Demo2 {
    public static void main1(String[] args) {
        Thread t = new MyThread2();
        t.start();
        while (true) {
            System.out.println("hello main!");
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

方法三: 創(chuàng)建一個匿名內(nèi)部類,繼承自Thread類,同時重寫run方法,同時再new出這個匿名內(nèi)部類的實例.

import java.util.*;
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("hello!");
    }
}
public class Demo3 {
    public static void main1(String[] args) {
        Thread t = new Thread(new MyRunnable());
        t.start();
    }

方法四: 同樣使用了匿名內(nèi)部類.

public class Demo4 {
    public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                System.out.println("hello thread");
            }
        };
        t.start();
    }
}

方法五: 使用了lambda表達式.

import java.util.*;
public class Demo5 {
    public static void main1(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello thread");
            }
        });
        t.start();
    }

串行執(zhí)行和并發(fā)執(zhí)行

public class Demo7 {
    private static final long count = 10_0000_0000;

    public static  void serial(){
        //吉利程序執(zhí)行時間
        long beg = System.currentTimeMillis();
        long a = 0;
        for (int i = 0; i < count; i++) {
            a++;
        }
        long b = 0;
        for (int i = 0; i < count; i++) {
            b++;
        }
        long end = System.currentTimeMillis();
        System.out.println("消耗時間: "+ (end - beg) + "ms");
    }
    public static void concurrency() throws InterruptedException {
        long beg = System.currentTimeMillis();
        Thread t1 = new Thread(()->{
            long a = 0;
            for (int i = 0; i < count; i++) {
                a++;
            }
        });
        t1.start();
        Thread t2 = new Thread(()->{
            long b = 0;
            for (int i = 0; i < count; i++) {
                b++;
            }
        });
        t2.start();
        //此處布恩那個直接記錄結(jié)束時間,別忘了,現(xiàn)在這個時間戳的代碼是在main 線程中
        //main t1 t2 是并發(fā)執(zhí)行關(guān)系,此處t1 t2 還沒執(zhí)行完呢,這里就開始記錄結(jié)束時間了,這顯然是不準確的.
        //正確做法應(yīng)該是讓main線程等地啊t1 t2跑完了,在記錄結(jié)束時間
        //join 效果就是等待線程結(jié)束,t1.join 就是讓main 線程等待 t1 結(jié)束,t2.join讓main 線程等待t2結(jié)束
        t1.join();
        t2.join();
        long end = System.currentTimeMillis();
        System.out.println("消耗時間: "+ (end - beg)+ "ms");
    }
    public static void main(String[] args)throws InterruptedException {
       // serial();
        concurrency();
    }
}

Thread中的一次額重要方法

1.start

決定了系統(tǒng)中是不是真的創(chuàng)建出線程,run單純的是一個普通的方法,描述了任務(wù)的內(nèi)容,start則是一個特殊的方法,內(nèi)部會在系統(tǒng)中創(chuàng)建線程.

public class Demo9 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while (true) {
                System.out.println("hello thread1");
                try {
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t.start();
        //t.run();
        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

run方法只是一個普通的方法,在main線程里面調(diào)用run,其實并沒有創(chuàng)建線程,這個循環(huán)仍是在main中執(zhí)行的.

中斷線程

中斷線程:讓一個線程停下來.

線程停下來的關(guān)鍵,是要讓對應(yīng)的run方法執(zhí)行完.

(1).可以手動設(shè)置一個標志位,來控制線程是否要執(zhí)行結(jié)束.

public class Demo10 {
    private  static boolean isQuit = false;
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while (!isQuit) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t.start();
        //只要把這個isQuit 設(shè)為true ,此時這個循環(huán)就退出了,進一步run 就執(zhí)行完了,再進一步就是線程結(jié)束了
        try{
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        isQuit = true;
        System.out.println("終止t線程");
    }
}

(2).使用thread中內(nèi)置的一個標志位來進行判定.

public class Demo11 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(!Thread.currentThread().isInterrupted()){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                    //當(dāng)觸發(fā)異常之后,立即就退出循環(huán)
                    break;
                }
            }
        });
        t.start();
        try{
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        //在線程中 調(diào)用interrupt 方法 來終端這個線程
        //t.interrupt 的意思是讓t線程被中斷!!
        t.interrupt();
    }
}

線程等待

多個線程之間,調(diào)度順序是不確定的,線程之間的執(zhí)行是按照調(diào)度器來安排的,這個過程可以視為無序或者隨機的,有些時候,我們需要控制線程的順序,線程等待就是其中一種手段,此處的線程等,主要控制線程結(jié)束的先后順.

join: 調(diào)用join的時候,那個線程調(diào)用的join,那個線程就會阻塞等待,等到對應(yīng)的線程執(zhí)行完畢為止(對應(yīng)線程的run執(zhí)行完).

public class Demo12 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello thread");
                try{
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t.start();
        //在主線程中可以使用一個等待操作,來等待t線程執(zhí)行結(jié)束
        try{
            t.join(10000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

線程休眠(sleep)

如果線程調(diào)用了sleep方法,這個PCB就會進入到阻塞隊列.

當(dāng)睡眠時間到了,系統(tǒng)就會把這個PCB從阻塞隊列挪回到就緒隊列.

實例:

public class Demo14 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (true) {
                //z這里啥都不能有
                try{
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t.start();
        Thread.sleep(1000);
        System.out.println(t.getState());
    }
}

到此這篇關(guān)于Java超詳細講解多線程中的Process與Thread的文章就介紹到這了,更多相關(guān)Java Process與Thread內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于SpringBoot中Ajax跨域以及Cookie無法獲取丟失問題

    關(guān)于SpringBoot中Ajax跨域以及Cookie無法獲取丟失問題

    這篇文章主要介紹了關(guān)于SpringBoot中Ajax跨域以及Cookie無法獲取丟失問題,本文具有參考意義,遇到相同或者類似問題的小伙伴希望可以從中找到靈感
    2023-03-03
  • 親身體驗Intellij?Idea從卡頓到順暢全過程

    親身體驗Intellij?Idea從卡頓到順暢全過程

    這篇文章主要介紹了親身體驗Intellij?Idea從卡頓到順暢全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 如何在 Java 中利用 redis 實現(xiàn) LBS 服務(wù)

    如何在 Java 中利用 redis 實現(xiàn) LBS 服務(wù)

    基于位置的服務(wù),是指通過電信移動運營商的無線電通訊網(wǎng)絡(luò)或外部定位方式,獲取移動終端用戶的位置信息,在GIS平臺的支持下,為用戶提供相應(yīng)服務(wù)的一種增值業(yè)務(wù)。下面我們來一起學(xué)習(xí)一下吧
    2019-06-06
  • Java二分查找算法實例詳解

    Java二分查找算法實例詳解

    在本篇文章里小編給大家分享總結(jié)的是一篇關(guān)于Java二分查找算法實例詳解內(nèi)容,對此有興趣的朋友們可以跟著學(xué)習(xí)下。
    2022-11-11
  • JVM 堆和棧的區(qū)別

    JVM 堆和棧的區(qū)別

    本文主要介紹了JVM堆和棧的區(qū)別。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • Java String 拼接字符串原理詳解

    Java String 拼接字符串原理詳解

    在本篇文章里小編給大家分享的是關(guān)于Java String 拼接字符串原理詳解的相關(guān)資源內(nèi)容,有需要的朋友們可以跟著學(xué)習(xí)參考下。
    2020-02-02
  • java?SpringMvc中攔截器的應(yīng)用

    java?SpringMvc中攔截器的應(yīng)用

    大家好,本篇文章主要講的是java?SpringMvc中攔截器的應(yīng)用,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • Java實現(xiàn)給Word文件添加文字水印

    Java實現(xiàn)給Word文件添加文字水印

    Word中設(shè)置水印時,可預(yù)設(shè)的文字或自定義文字設(shè)置為水印效果,但通常添加水印效果時,會對所有頁面都設(shè)置成統(tǒng)一效果。本文將利用Java給Word每一頁設(shè)置不同文字水印效果,需要的可以參考一下
    2022-02-02
  • Springboot整合第三方登錄功能的實現(xiàn)示例

    Springboot整合第三方登錄功能的實現(xiàn)示例

    本文主要介紹了Springboot整合第三方登錄功能的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • SpringMVC攔截器超詳細解讀

    SpringMVC攔截器超詳細解讀

    SpringMVC的處理器攔截器,類似于Servlet開發(fā)中的過濾器Filter,用于對處理器進行預(yù)處理和后處理。?依賴于web框架,在實現(xiàn)上基于Java的反射機制,屬于面向切面編程(AOP)的一種運用
    2022-07-07

最新評論