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

Java線程狀態(tài)及同步鎖的操作方法

 更新時間:2021年11月15日 17:14:48   作者:Thales_ZeeWay  
Java中的thread類自帶有線程的一些方法,這些方法可以讓線程睡眠,插隊,提高線程調(diào)度的優(yōu)先級等等,它們提供了改變線程狀態(tài)的操作手段,這篇文章主要介紹了Java線程狀態(tài)及同步鎖,需要的朋友可以參考下

線程的生命歷程

線程的五大狀態(tài)

  • 創(chuàng)建狀態(tài):簡而言之,當創(chuàng)建線程對象的代碼出現(xiàn)的時候,此時線程就進入了創(chuàng)建狀態(tài)。這時候的線程只是行代碼而已。只有調(diào)用線程的start()方法時,線程的狀態(tài)才會改變,進入就緒狀態(tài)
  • 就緒狀態(tài):在這個狀態(tài)下的線程,已經(jīng)做好了隨時運行的準備,但是并不意味著會立刻開始運行。還需要等待CPU的隨機調(diào)度,隨機運行。只有當線程被CPU調(diào)度運行成功,此時的線程才算是進入下一個狀態(tài)——運行狀態(tài)。
  • 運行狀態(tài):線程處于運行狀態(tài),主要是在運行線程中的代碼塊。
  • 阻塞狀態(tài):在線程運行過程中,當線程代碼塊中調(diào)用了線程的sleep(),yield(),同步鎖定或者其他使線程阻塞的方法,此時的線程無法繼續(xù)運行下去,進入了阻塞狀態(tài)(線程代碼塊的自身邏輯混亂也可以使線程阻塞)。當造成線程阻塞的阻塞事件解決之后,線程不會回到運行狀態(tài),而是回到就緒狀態(tài),再次等待CPU的調(diào)度運行。需要注意的是,阻塞并不意味著線程運行終止
  • 死亡狀態(tài):當線程成功運行完所有的代碼之后,線程就結(jié)束了,也進入了死亡狀態(tài)。線程一旦死亡,就無法再次啟動,注意這里和阻塞狀態(tài)的不同。同樣的,當線程運行一半的時候被強行結(jié)束終止,也算進入死亡狀態(tài),也無法被再次啟動。

線程的方法

Java中的thread類自帶有線程的一些方法,這些方法可以讓線程睡眠,插隊,提高線程調(diào)度的優(yōu)先級等等,它們提供了改變線程狀態(tài)的操作手段。(不過在JDK幫助文檔中,一些方法已經(jīng)不推薦使用)

線程方法中的一些有趣的地方

  • 線程睡眠是以毫秒為單位的。一秒等于一千毫秒。一般在測試程序中調(diào)用睡眠方法,是為了提高程序問題的發(fā)生性,或者說為了發(fā)現(xiàn)bug
  • 線程停止,由于Java中自帶的停止方法不太好用,所以一般都是自己寫一個停止的方法,標定一個布爾類型的Flag作為線程執(zhí)行的標志,當flag為真時線程運行,當flag為假時線程停止。
  • 線程禮讓是將正在運行的線程暫?;氐骄途w狀態(tài),而不是變?yōu)樽枞麪顟B(tài)。有趣的是禮讓不是一定會成功的,因為線程由就緒狀態(tài)進入運行狀態(tài)是由CPU隨機調(diào)度的。所以禮讓的線程有可能在下次的調(diào)度中再次提前調(diào)度,提前運行。
  • 線程插隊(join方法),強制阻塞其他線程,只有插入的線程執(zhí)行完成之后,其他線程才能繼續(xù)執(zhí)行
  • 線程雖然有優(yōu)先級的區(qū)別(1-10),但是在實際運行中還是得看CPU的心情調(diào)度運行,優(yōu)先級高只是被調(diào)度的概率高一點。Java中自帶有線程優(yōu)先級的查看和改變方法(線程的優(yōu)先級設(shè)置最好在線程啟動之前)
public class ttp {
    public static void main(String[] args) {
        //主線程的默認優(yōu)先級
        System.out.println(Thread.currentThread().getName()+"--->" + Thread.currentThread().getPriority());
        MyPriorty mm = new MyPriorty();
        Thread t1 = new Thread(mm);
        Thread t2 = new Thread(mm);
        Thread t3 = new Thread(mm);


        
        t1.setPriority(10);
        t1.start();

        t2.setPriority(4);
        t2.start();

        t3.setPriority(6);
        t3.start();


    }
}

//Runnable接口實現(xiàn)接口,run方法為打印線程名稱和線程的優(yōu)先級
class MyPriorty implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"--->" + Thread.currentThread().getPriority());
    }
}
//這里的輸出有多種結(jié)果,因為優(yōu)先級只是增加了線程被調(diào)度運行的機率

用戶線程和守護線程。守護線程的作用是保證用戶線程的執(zhí)行過程正常,例如Java中的內(nèi)存回收線程和后臺記錄操作日志等等,這些都是守護線程。虛擬機必須等待用戶線程執(zhí)行完畢,不用等待守護線程執(zhí)行完畢。當用戶線程完成后,虛擬機就自動關(guān)閉,守護線程也就自動死亡了。

//Java的Thread類自帶設(shè)置守護線程的方法
Thread.setdaemon(true) //設(shè)置為守護線程
//一般我們創(chuàng)建的線程默認都是用戶線程

線程同步。線程同步是出現(xiàn)多個線程訪問同一個對象并都想對其進行操作的時候必須考慮的問題。不進行線程同步(并發(fā))控制的多線程是不安全的。

//線程不安全,出現(xiàn)了-1張票以及有兩個線程拿到同一張票的錯誤,所以這是一個不安全的線程
public class test05 {

    public static void main(String[] args) {
        buyTicket b1 = new buyTicket();
        Thread t1 = new Thread(b1,"you");
        Thread t2 = new Thread(b1,"i");
        Thread t3 = new Thread(b1,"he");
        Thread t4 = new Thread(b1,"she");
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}


class buyTicket implements Runnable{
    //剩余票數(shù)
    private int ticketNums = 12;
    private boolean flag = true;

    @Override
    public void run() {
        while(flag){
            buy();
        }
    }

    private void buy(){
        if(ticketNums <= 0){
            flag = false;
            return;
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "買到了第" + ticketNums-- + "張票");
    }
}

線程同步

線程同步實質(zhì)上是一個等待機制。線程同步時會將多個線程放入對象等待池中進行排隊(隊列),等待前一個線程執(zhí)行操作完畢,再有下一個線程進行執(zhí)行操作。每個對象都有一個獨有的鎖(排他鎖),每個線程執(zhí)行時都會獲得對象的排他鎖,這樣只有獲得鎖的線程可以對對象進行操作,執(zhí)行結(jié)束后排他鎖被下一個線程獲得。總結(jié)來說,線程同步的形成條件就是:隊列+鎖。

在訪問時加入鎖機制synchronized,當一個線程獲得對象得排他鎖,獨占資源,其他線程必須等待,使用后釋放鎖即可

線程同步也有一些存在的問題(大部分是以犧牲性能以保證安全)

  • 一個線程持有鎖會導(dǎo)致其他所有需要此鎖的線程掛起
  • 在多線程競爭下,加鎖,釋放鎖會導(dǎo)致較多的上下文切換和調(diào)度延時,引起性能問題
  • 如果一個優(yōu)先級高的線程等待一個優(yōu)先級低的線程釋放鎖,會導(dǎo)致優(yōu)先級倒置,引起性能問題

一般來說,synchronized是方法聲明中添加,默認對方法中的this對象資源添加鎖。如果要對其他共享資源對象進行鎖定,則要使用同步監(jiān)視器

  • 一號線程訪問,鎖定監(jiān)視器,開始執(zhí)行中間的代碼
  • 二號線程訪問,發(fā)現(xiàn)監(jiān)視器被鎖,無法訪問,掛起
  • 一號線程執(zhí)行完畢,解鎖監(jiān)視器
  • 二號線程訪問,監(jiān)視器無鎖,鎖定并執(zhí)行代碼
public void xxx(){
    //其中ob就是想要鎖住的任意的共享資源對象
    //代碼塊是放在同步監(jiān)視器中的
    synchronized(obj){
        ....
    }
}

需要注意的是,這樣的鎖理論上是可行的 ,但是在實際運行中雖然加了鎖,但是還是有可能出現(xiàn)不安全的現(xiàn)象

到此這篇關(guān)于Java線程狀態(tài)及同步鎖的文章就介紹到這了,更多相關(guān)Java線程狀態(tài)及同步鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Struts2學習筆記(7)-訪問Web元素

    Struts2學習筆記(7)-訪問Web元素

    這篇文章主要介紹Struts2中訪問Web元素的方法,希望能給大家做一個參考。
    2016-06-06
  • idea為java程序添加啟動參數(shù)的問題解析(program?arguments,vm?arguments,Environment?variable)并在程序中獲取使用

    idea為java程序添加啟動參數(shù)的問題解析(program?arguments,vm?arguments,Envi

    這篇文章主要介紹了idea為java程序添加啟動參數(shù)的問題解析(program?arguments,vm?arguments,Environment?variable)并在程序中獲取使用,本文給大家分享問題描述及解決方法,需要的朋友可以參考下
    2023-09-09
  • Java協(xié)程編程之Loom項目實戰(zhàn)記錄

    Java協(xié)程編程之Loom項目實戰(zhàn)記錄

    這篇文章主要介紹了Java協(xié)程編程之Loom項目嘗鮮,如果用嘗鮮的角度去使用Loom項目,可以提前窺探JVM開發(fā)者們是如何基于協(xié)程這個重大特性進行開發(fā)的,這對于提高學習JDK內(nèi)核代碼的興趣有不少幫助,需要的朋友可以參考下
    2021-08-08
  • java子類繼承父類實例-披薩的選擇實現(xiàn)代碼

    java子類繼承父類實例-披薩的選擇實現(xiàn)代碼

    這篇文章主要介紹了java子類繼承父類實例-披薩的選擇實現(xiàn)代碼,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • 最新評論