最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

新手了解java 多線程基礎(chǔ)知識(shí)

 更新時(shí)間:2021年07月05日 17:12:36   作者:王星偉QAQ  
這篇文章主要介紹了java 基礎(chǔ)教程之多線程詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,線程的基本屬性、如何創(chuàng)建線程、線程的狀態(tài)切換以及線程通信,需要的朋友可以參考下

一、線程的生命周期

JDK中用Thread.State類定義了線程的幾種狀態(tài):

要想實(shí)現(xiàn)多線程,必須在主線程中創(chuàng)建新的線程對(duì)象。Java語(yǔ)言使用 Thread類及其子類的對(duì)象來(lái)表示線程,在它的一個(gè)完整的生命周期中通常 要經(jīng)歷如下的五種狀態(tài):

  • 新建:當(dāng)一個(gè)Thread類或其子類的對(duì)象被聲明并創(chuàng)建時(shí),新生的線程 對(duì)象處于新建狀態(tài);
  • 就緒:處于新建狀態(tài)的線程被start()后,將進(jìn)入線程隊(duì)列等待CPU時(shí)間 片,此時(shí)它已具備了運(yùn)行的條件,只是沒分配到CPU資源;
  • 運(yùn)行:當(dāng)就緒的線程被調(diào)度并獲得CPU資源時(shí),便進(jìn)入運(yùn)行狀態(tài), run()方法定義了線程的操作和功能;
  • 阻塞:在某種特殊情況下,被人為掛起或執(zhí)行輸入輸出操作時(shí),讓出 CPU 并臨時(shí)中止自己的執(zhí)行,進(jìn)入阻塞狀態(tài);
  • 死亡:線程完成了它的全部工作或線程被提前強(qiáng)制性地中止或出現(xiàn)異常 導(dǎo)致結(jié)束。 在上面五個(gè)階段中,只有新建和死亡是不可重復(fù),其它幾個(gè)狀態(tài)都可能改變。

在這里插入圖片描述

注意:

1.新建和死亡狀態(tài)只能有一次;

2.運(yùn)行狀態(tài)只能是從就緒狀態(tài)變過來(lái)的;

3.阻塞狀態(tài)不能直接變?yōu)檫\(yùn)行狀態(tài),需要通過就緒狀態(tài);

4.當(dāng)一個(gè)運(yùn)行狀態(tài)的線程調(diào)用yield()方法后,就會(huì)變?yōu)榫途w狀態(tài);

5.當(dāng)一個(gè)運(yùn)行狀態(tài)的線程調(diào)用sleep()、等待同步鎖方法、wait()方法或 join()方法時(shí),就會(huì)處理阻塞狀態(tài);

6.當(dāng)一個(gè)阻塞狀態(tài)的線程調(diào)用notify()/notifyAll()方法,或者sleep()方法 結(jié)束,再或者獲得同步鎖,或者join()線程執(zhí)行完畢就可以變?yōu)榫途w狀 態(tài)的線程

7.當(dāng)一個(gè)線程執(zhí)行過多后就處理死亡狀態(tài),即線程生命周期結(jié)束。

二、線程同步

1、為什么要有線程同步

為了解決線程安全問題,在多線程下,多個(gè)線程對(duì)一個(gè)數(shù)據(jù)進(jìn)行修改時(shí),可能會(huì)產(chǎn)生數(shù)據(jù)出錯(cuò)的問題,所以我們就需要通過線程同步的方法來(lái)解決問題。

Java中的線程同步實(shí)現(xiàn)方式:

2、synchronized

2.1同步代碼塊

示例:

public class MyRunnableTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();

        Thread thread = new Thread(myRunnable,"A");
        Thread thread1 = new Thread(myRunnable,"B");
        Thread thread2 = new Thread(myRunnable,"C");
        Thread thread3 = new Thread(myRunnable,"D");
        Thread thread4 = new Thread(myRunnable,"E");
        thread.start();
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
    public class MyRunnable implements Runnable{
        @Override
        public void run() {
            synchronized (Thread.class){
                System.out.println(Thread.currentThread().getName()+"在過山洞");
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

注意: 同步鎖可以是任意對(duì)象,但該對(duì)象必須唯一; 同步代碼塊所在位置也很重要,同步代碼塊需要把引起數(shù)據(jù)問題的所有代碼都包裹起,不能多裹,也不能少裹。 我們通常都是使用字節(jié)碼文件來(lái)作為同步鎖。

2.2同步方法

示例:

public class MyRunnableTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();

        Thread thread = new Thread(myRunnable,"A");
        Thread thread1 = new Thread(myRunnable,"B");
        Thread thread2 = new Thread(myRunnable,"C");
        Thread thread3 = new Thread(myRunnable,"D");
        Thread thread4 = new Thread(myRunnable,"E");
        thread.start();
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
    public class MyRunnable implements Runnable{
        @Override
        public void run() {
            test()
        }
 public synchronized void test(){
        System.out.println(Thread.currentThread().getName()+"在過山洞");
        try {
             Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

**注意:**當(dāng)使用同步方法來(lái)處理多線程的共享數(shù)據(jù)問題,如果是靜態(tài)方法,使用的是類名.class方式,如果是非靜態(tài)方法,使用的是this。

3、Lock鎖

使用Lock.lock()進(jìn)行加鎖操作,然后使用Lock.unlock()方法來(lái)進(jìn)行 解鎖。

Lock是一個(gè)接口,不能直接實(shí)例化,需要使用子類來(lái)實(shí)例化,通常使用的 子類是ReentrantLock。

public class MyRunnableTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable,"A");
        Thread thread1 = new Thread(myRunnable,"B");
        Thread thread2 = new Thread(myRunnable,"C");
        Thread thread3 = new Thread(myRunnable,"D");
        Thread thread4 = new Thread(myRunnable,"E");
        thread.start();
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}
public class MyRunnable implements Runnable{
    Lock lock = new ReentrantLock();
        lock.lock();
        System.out.println(Thread.currentThread().getName()+"在過山洞");
        try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
            lock.unlock();
        }
        }
    }

說明:

在需要作同步操作的代碼塊之前需要使用Lock.lock()方法來(lái)作加鎖處 理;在同步操作的代碼塊之后,增加finally語(yǔ)句塊來(lái)釋放鎖,釋放鎖的方法為L(zhǎng)ock.unlock()方法;一定要確保鎖能釋放,否則就是死鎖;

Lock比synchronized更輕量級(jí),功能更強(qiáng)大,如果可以盡量使用Lock。

四.基本概念

程序、進(jìn)程、線程

  • 程序(program)是為完成特定任務(wù)、用某種語(yǔ)言編寫的一組指令的集 合。即指一段靜態(tài)的代碼,靜態(tài)對(duì)象。
  • 進(jìn)程(process)是程序的一次執(zhí)行過程,或是正在運(yùn)行的一個(gè)程序。是 一個(gè)動(dòng)態(tài)的過程:有它自身的產(chǎn)生、存在和消亡的過程——具有生命 周期??梢岳斫鉃橐粋€(gè)正在運(yùn)行的軟件。
  • 線程(thread),進(jìn)程可進(jìn)一步細(xì)化為線程,是一個(gè)程序內(nèi)部的一條執(zhí)行 路徑??梢岳斫鉃橐粋€(gè)軟件的功能。

多線程程序的優(yōu)點(diǎn):

  • 提高應(yīng)用程序的響應(yīng)。對(duì)圖形化界面更有意義,可增強(qiáng)用戶體驗(yàn)。
  • 提高計(jì)算機(jī)系統(tǒng)CPU的利用率。
  • 改善程序結(jié)構(gòu)。將既長(zhǎng)又復(fù)雜的進(jìn)程分為多個(gè)線程,獨(dú)立運(yùn)行,利于理 解和修改。

五.多線程的創(chuàng)建

​ 在Java中我們可以使用java.lang.Thread類來(lái)實(shí)現(xiàn) ,要想我們的類具有多線程的功能,需要讓我們的類去繼承Thread類,然后重寫run()方法,并調(diào)用 start()方法來(lái)啟動(dòng)多線程。

示例 1:

public class MyThread extends Thread{
    public void run(){
        for (int i = 0; i < 50; i++) {
            System.out.println("MyThread:"+i);
        }
    }
}
public class MyThreadTest{
    public static void main(String[] args){
        Thread t1 = new MyThread();
        t1.start();
        for (int i = 0; i < 20; i++) {
            System.out.println("world=====" + i);
        }
    }
}

說明:創(chuàng)建一個(gè)Java類繼承Thread類,并重寫父類Thread中的run方法,在run方法中寫具體的多線程業(yè)務(wù)。創(chuàng)建線程類的對(duì)象,并調(diào)用start方法啟動(dòng)多線程。

**注意:**多線程的啟動(dòng)調(diào)用的是start方法,在jvm底層中start方法內(nèi)部會(huì)調(diào)用run方法。

一個(gè)對(duì)象只需要調(diào)用一次start()方法,如果多次調(diào)用則會(huì)拋出異?!癐llegalThreadStateException”。

示例 2:

public class MyRunnable implements Runnable {
    public void run() {
        for (int i = 0; i < 50 ; i++) {
            System.out.println( "MyRunnable:"+i);
        }
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        Thread thread = new Thread( new MyRunnable());
        thread.start();// 只有調(diào)用Thread類中的start()方法才可以實(shí)現(xiàn)多線程
            for (int i = 0; i < 50; i++) {
                System.out.println("main:" + i);
            }
    }
}

說明:

  • 編寫一個(gè)類,實(shí)現(xiàn)Runnable接口;
  • 重寫run()方法;
  • 根據(jù)Runnable子類對(duì)象來(lái)創(chuàng)建Thread對(duì)象;
  • 通過Thread對(duì)象調(diào)用start()方法來(lái)啟動(dòng)多線程;

總結(jié):

  • 繼承Thread:重寫run()方法,業(yè)務(wù)代碼在run()中。
  • 實(shí)現(xiàn)Runnable:線程代碼存在接口的子類的run方法。
  • 通過Callable和線程池的方式創(chuàng)建線程。

**提示:**在應(yīng)用中我們?nèi)绻梢允褂肦unable接口那么就盡量使用,這樣可以避免Java單繼承的局限。

六.Thread類方法介紹

1)currentThread():返回當(dāng)前正在執(zhí)行的線程對(duì)象的引用。

2)getName():返回當(dāng)前線程的名稱

3)isAlive():判斷當(dāng)前線程是否存活

4)isDeaomon():判斷線程是否為守護(hù)線程

5)join():在當(dāng)前線程中引入另一個(gè)線程,而當(dāng)前線程會(huì)被阻塞

6)sleep():讓當(dāng)前線程進(jìn)入睡眠狀態(tài)

7)yield():讓當(dāng)前線程放棄CPU的執(zhí)行權(quán),重新進(jìn)入排隊(duì),與其他線程平等爭(zhēng)奪CPU執(zhí)行。

8)interrupt() 中斷線程 9)interrupted() 如果當(dāng)前線程已經(jīng)中斷,則返回 true;否則返回 false。

示例:

public class ThreadTest {
    public static void main(String[] args) {
        //創(chuàng)建線程并開啟線程1
        Thread thread = new MyThread();
        thread.start();
        //創(chuàng)建線程并開啟線程2
        Thread thread1 = new Thread(new MyRunnable());
        thread1.start();
        //創(chuàng)建線程并開啟線程3
        MyCallable myCallable = new MyCallable();
        FutureTask futureTask = new FutureTask(myCallable);
        new Thread(futureTask).start();

        for (int i = 0; i < 100; i++) {
            if (i== 50){
                //在main線程中當(dāng)i=50加如thread線程,會(huì)在thread執(zhí)行完后才會(huì)繼續(xù)執(zhí)行main線程剩下的
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("main:"+i);
        }
    }
}

public class MyThread extends Thread{
    public void run(){
        for (int i = 0; i < 100; i++) {
            // void interrupt() 中斷線程 可以理解為線程中斷狀態(tài)有 true | false,每一次調(diào)用就是修改狀態(tài)為true
            //static boolean interrupted() 如果當(dāng)前線程已經(jīng)中斷,則返回 true;否則返回 false。
            Thread.currentThread().interrupt();
            if (Thread.interrupted()){
                System.out.println("Thread interrupted");
            }
            // static currentThread()  返回對(duì)當(dāng)前正在執(zhí)行的線程對(duì)象的引用
            //String getName()   返回該線程的名稱。
            //Thread.currentThread().getName()  獲取當(dāng)前線程對(duì)象的名稱
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyRunnable"+i);
            //每次執(zhí)行完打印讓線程休眠1秒
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class MyCallable implements Callable {
    @Override
    public Object call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyCallable:"+i);
        }
        return null;
    }
}

總結(jié)

本篇文章就到這里了,希望對(duì)你有所幫助,也希望你能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • 使用Java將一個(gè)List運(yùn)用遞歸轉(zhuǎn)成樹形結(jié)構(gòu)案例

    使用Java將一個(gè)List運(yùn)用遞歸轉(zhuǎn)成樹形結(jié)構(gòu)案例

    這篇文章主要介紹了使用Java將一個(gè)List運(yùn)用遞歸轉(zhuǎn)成樹形結(jié)構(gòu)案例,本文通過詳細(xì)的案例來(lái)解釋說明了如何去操作,需要的朋友可以參考下
    2021-06-06
  • Springboot中的Controller解析

    Springboot中的Controller解析

    這篇文章主要介紹了Springboot中的Controller解析,Controller是SpringBoot的基本組件,也是MVC結(jié)構(gòu)的組成部分,其作用是將用戶提交來(lái)的請(qǐng)求通過URL匹配,分發(fā)給不同的接收器,該接收器會(huì)對(duì)其進(jìn)行相應(yīng)處理,然后返回處理結(jié)果,需要的朋友可以參考下
    2023-09-09
  • MyBatis Plus Mapper CRUD接口測(cè)試方式

    MyBatis Plus Mapper CRUD接口測(cè)試方式

    在數(shù)據(jù)庫(kù)管理系統(tǒng)中,插入記錄是添加新數(shù)據(jù)條目,而刪除操作包括根據(jù)主鍵ID單條刪除和批量刪除,也可以基于特定條件進(jìn)行刪除,刪除操作的SQL語(yǔ)句是通過鍵值對(duì)在Map中拼接而成,如delete from 表 where key1=value1 AND key2=value2
    2024-09-09
  • SpringBoot中事務(wù)失效的原因詳解

    SpringBoot中事務(wù)失效的原因詳解

    這篇文章主要介紹了SpringBoot中事務(wù)失效的原因詳解,spring中的事務(wù)是依賴AOP的,AOP是通過動(dòng)態(tài)代理實(shí)現(xiàn)的,只有通過代理類訪問的方法才能被攔截,需要的朋友可以參考下
    2023-10-10
  • 使用Spring Boot Maven插件的詳細(xì)方法

    使用Spring Boot Maven插件的詳細(xì)方法

    這篇文章主要介紹了如何使用Spring Boot Maven插件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • SpringBoot實(shí)現(xiàn)物品收藏功能

    SpringBoot實(shí)現(xiàn)物品收藏功能

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)物品收藏功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 使用springboot的jar包能夠以service方式啟動(dòng)

    使用springboot的jar包能夠以service方式啟動(dòng)

    這篇文章主要介紹了使用springboot的jar包能夠以service方式啟動(dòng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot程序打包失敗(.jar中沒有主清單屬性)

    SpringBoot程序打包失敗(.jar中沒有主清單屬性)

    在學(xué)習(xí)SpringBoot,打包SpringBoot程序后,在cmd運(yùn)行出現(xiàn)了 某某某.jar中沒有注清單屬性,本文就來(lái)介紹一下原因以及解決方法,感興趣的可以了解一下
    2023-06-06
  • 最新評(píng)論

    兰西县| 永兴县| 涟水县| 龙口市| 灯塔市| 芦山县| 廊坊市| 乌恰县| 淳安县| 常山县| 长宁区| 昌平区| 安图县| 修文县| 抚远县| 肃北| 庄浪县| 安龙县| 凌海市| 庆云县| 钟祥市| 马龙县| 抚松县| 剑川县| 平陆县| 汉沽区| 蒙阴县| 宿州市| 徐闻县| 双牌县| 微山县| 繁峙县| 岑巩县| 九江县| 即墨市| 高碑店市| 天津市| 广平县| 汝城县| 安陆市| 德令哈市|