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

JAVA多線程知識(shí)匯總

 更新時(shí)間:2020年07月30日 10:30:09   作者:擱淺Lee  
這篇文章主要介紹了JAVA多線程的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

線程概念

進(jìn)程:?jiǎn)?dòng)一個(gè)應(yīng)用程序就叫一個(gè)進(jìn)程。 接著又啟動(dòng)一個(gè)應(yīng)用程序,這叫兩個(gè)進(jìn)程。每個(gè)進(jìn)程都有一個(gè)獨(dú)立的內(nèi)存空間;進(jìn)程也是程序的一次執(zhí)行過(guò)程,是系統(tǒng)運(yùn)行程序的基本單位;系統(tǒng)運(yùn)行一個(gè)程序即是一個(gè)進(jìn)程從創(chuàng)建、運(yùn)行到消亡的過(guò)程。

線程:線程是在進(jìn)程內(nèi)部同時(shí)做的事情,一個(gè)進(jìn)程中可以有多個(gè)線程,這個(gè)應(yīng)用程序也可以稱之為多線程程序。

一個(gè)程序運(yùn)行后至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程中可以包含多個(gè)線程

線程調(diào)度:

  • 分時(shí)調(diào)度:所有線程輪流使用 CPU 的使用權(quán),平均分配每個(gè)線程占用 CPU 的時(shí)間。
  • 搶占式調(diào)度:優(yōu)先讓優(yōu)先級(jí)高的線程使用 CPU,如果線程的優(yōu)先級(jí)相同,那么會(huì)隨機(jī)選擇一個(gè)(線程隨機(jī)性),Java使用的為搶占式調(diào)度。

創(chuàng)建多線程

方法一:創(chuàng)建Thread類的子類

  • 創(chuàng)建Thread類的子類,并重寫(xiě)該類的run()方法,設(shè)置線程任務(wù)。
  • 創(chuàng)建Thread子類的實(shí)例,即創(chuàng)建了線程對(duì)象
  • 調(diào)用線程對(duì)象的start()方法來(lái)啟動(dòng)該線程
//方法一:
//定義Thread類的子類,并重寫(xiě)該類的run()方法
public class MyThreadDemo01 extends Thread {
  @Override
  public void run() {
    for (int i = 0; i < 20 ; i++) {
      System.out.println(getName()+"-->"+i);
    }
  }
}
//主線程
public class MainThread01 {
  public static void main(String[] args) {
    //創(chuàng)建Thread子類的實(shí)例,即創(chuàng)建了線程對(duì)象
    MyThreadDemo01 thread01 = new MyThreadDemo01();

    //調(diào)用線程對(duì)象的start()方法來(lái)啟動(dòng)該線程
    thread01.start();

    for (int i = 0; i < 10 ; i++) {
      System.out.println(Thread.currentThread().getName()+"-->"+i);
    }
  }
}

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

public String getName() :獲取當(dāng)前線程名稱。

public void start() :導(dǎo)致此線程開(kāi)始執(zhí)行; Java虛擬機(jī)調(diào)用此線程的run方法。

public void run() :此線程要執(zhí)行的任務(wù)在此處定義代碼。

public static void sleep(long millis) :使當(dāng)前正在執(zhí)行的線程以指定的毫秒數(shù)暫停(暫時(shí)停止執(zhí)行)。

方法二:實(shí)現(xiàn)Runnable接口

  • 定義Runnable接口的實(shí)現(xiàn)類,并重寫(xiě)該接口的run()方法,設(shè)置線程任務(wù)
  • 創(chuàng)建Runnable實(shí)現(xiàn)類對(duì)象
  • 創(chuàng)建Thread類的對(duì)象,并且該對(duì)象構(gòu)造方法中傳遞Runnable實(shí)現(xiàn)類對(duì)象
  • 調(diào)用Thread對(duì)象的start()方法來(lái)啟動(dòng)線程
//方法二:
//定義Runnable接口的實(shí)現(xiàn)類,并重寫(xiě)該接口的run()方法,設(shè)置線程任務(wù)
public class MyThreadDemo02 implements Runnable{
  @Override
  public void run() {
    for (int i = 0; i < 10 ; i++) {
      System.out.println(Thread.currentThread().getName()+"-->"+i);
    }
  }
}
 //主線程
public class MainThread {
  public static void main(String[] args) {  
    //創(chuàng)建Runnable實(shí)現(xiàn)類對(duì)象
    MyThreadDemo02 runnable = new MyThreadDemo02();

    //創(chuàng)建Thread類的對(duì)象,并且該對(duì)象構(gòu)造方法中傳遞Runnable實(shí)現(xiàn)類對(duì)象
    Thread thread02 = new Thread(runnable);

    //調(diào)用Thread對(duì)象的start()方法來(lái)啟動(dòng)線程
    thread02.start();

    for (int i = 0; i < 20 ; i++) {
      System.out.println(Thread.currentThread().getName()+"-->"+i);
    }
  }
}

方法三:匿名內(nèi)部類方式

  • 匿名內(nèi)部類能夠簡(jiǎn)化程序
//方法三:匿名內(nèi)部類
public class MainThread {
  public static void main(String[] args) {
    //Thread方式
    new Thread(){
      @Override
      public void run() {
        for (int i = 0; i < 10 ; i++) {
          System.out.println(Thread.currentThread().getName()+"-->"+i);
        }
      }
    }.start();
    //Runnable接口方式
	 new Thread(new Runnable() {
      @Override
      public void run() {
        for (int i = 0; i < 10 ; i++) {
          System.out.println(Thread.currentThread().getName()+"-->"+i);
        }
      }
    }).start();
    ////////////////////////////////////////////////

    for (int i = 0; i < 20 ; i++) {
      System.out.println(Thread.currentThread().getName()+"-->"+i);
    }
  }
}

線程安全問(wèn)題

多線程訪問(wèn)共享數(shù)據(jù),,且多個(gè)線程中對(duì)資源有寫(xiě)的操作,就會(huì)出現(xiàn)線程安全問(wèn)題

線程安全問(wèn)題都是由全局變量及靜態(tài)變量引起的。若每個(gè)線程中對(duì)全局變量、靜態(tài)變量只有讀操作,而無(wú)寫(xiě)操作,一般來(lái)說(shuō),這個(gè)全局變量是線程安全的;若有多個(gè)線程同時(shí)執(zhí)行寫(xiě)操作,一般都需要考慮線程同步, 否則的話就可能影響線程安全。

解決線程安全問(wèn)題采用線程同步機(jī)制,主要有以下三種方式:

  • 同步代碼塊
  • 同步方法
  • 鎖機(jī)制

同步代碼塊

同步代碼塊:synchronized 關(guān)鍵字可以用于方法中的某個(gè)區(qū)塊中,表示只對(duì)這個(gè)區(qū)塊的資源實(shí)行互斥訪問(wèn)。

  • 格式:synchronized(鎖對(duì)象){ //訪問(wèn)共享數(shù)據(jù)的代碼 }
  • 鎖對(duì)象可以是任意類型
  • 多個(gè)線程對(duì)象要使用同一把鎖
  • 鎖對(duì)象是將同步代碼塊鎖住,只讓線程在同步代碼塊中執(zhí)行
public class SafeRunnableDemo implements Runnable {
  private int ticket = 100;

  //同步代碼塊
  //創(chuàng)建鎖對(duì)象
  Object lock = new Object();

  @Override
  public void run() {
    while (true){
      //鎖住同步代碼塊
      synchronized (lock){
        if (ticket > 0) {
          System.out.println(Thread.currentThread().getName() + "正在賣第" + ticket + "張");
          ticket--;
        }
      }
    }
  }
}

同步方法

同步方法:使用synchronized修飾的方法,就叫做同步方法,保證A線程執(zhí)行該方法的時(shí)候,其他線程只能在方法外等著

  • 格式:修飾符 synchronized 返回值類型 方法名(參數(shù)列表) { //訪問(wèn)共享數(shù)據(jù)的代碼 }
  • 把共享了同步數(shù)據(jù)的代碼抽取出來(lái),放入同步方法中
public class SafeRunnableDemo implements Runnable {
  private int ticket = 100;

  //同步方法
  //定義一個(gè)同步方法
  public synchronized void lock(){
    //同步方法鎖住代碼塊
    if (ticket > 0) {
      System.out.println(Thread.currentThread().getName() + "正在賣第" + ticket + "張");
      ticket--;
    }
  }

  //重寫(xiě)run并使用同步方法
  @Override
  public void run() {
    while (true){
      lock();
    }
  }
}

Lock鎖

Lock提供了比synchronized更廣泛的鎖操作

  • 在Lock接口中 void lock() 獲取鎖,void unlock() 釋放鎖
  • 需要在成員位置處創(chuàng)建ReentraLock對(duì)象,在共享數(shù)據(jù)代碼塊之前調(diào)用方法lock()獲取鎖,在之后用unlock()方法釋放鎖
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SafeRunnableDemo implements Runnable {
  private int ticket = 100;

  //Lock鎖方法
  //創(chuàng)建ReentrantLock對(duì)象
  Lock lock = new ReentrantLock();
  @Override
  public void run() {
    while (true){
      //在可能出現(xiàn)問(wèn)題的代碼塊之前用lock()方法
      lock.lock();
      if (ticket > 0) {
        System.out.println(Thread.currentThread().getName() + "正在賣第" + ticket + "張");
        ticket--;
      }
      //在可能出現(xiàn)問(wèn)題的代碼塊之后用unlock()方法
      lock.unlock();
    }
  }
}

線程機(jī)制

  • NEW(新建):線程剛被創(chuàng)建,但是并未啟動(dòng)。還沒(méi)調(diào)用start()方法。
  • Runnable(可運(yùn)行):線程可以在java虛擬機(jī)中運(yùn)行的狀態(tài),可能正在運(yùn)行自己代碼,也可能沒(méi)有,這取決于操作系統(tǒng)處理器。
  • Blocked(鎖阻塞):當(dāng)一個(gè)線程試圖獲取一個(gè)對(duì)象鎖,而該對(duì)象鎖被其他的線程持有,則該線程進(jìn)入Blocked狀態(tài);當(dāng)該線程持有鎖時(shí),該線程將變成Runnable狀態(tài)。
  • Waiting(無(wú)限等待):一個(gè)線程在等待另一個(gè)線程執(zhí)行一個(gè)(喚醒)動(dòng)作時(shí),該線程進(jìn)入Waiting狀態(tài)。進(jìn)入這個(gè)狀態(tài)后是不能自動(dòng)喚醒的,必須等待另一個(gè)線程調(diào)用notify()或者notifyAll()方法才能夠喚醒。
  • Timed Waiting(計(jì)時(shí)等待):同waiting狀態(tài),有幾個(gè)方法有超時(shí)參數(shù),調(diào)用他們將進(jìn)入Timed Waiting狀態(tài)。這一狀態(tài) 將一直保持到超時(shí)期滿或者接收到喚醒通知。帶有超時(shí)參數(shù)的常用方法有Thread.sleep()、Object.wait()。
  • Teminated(被終止):因?yàn)閞un方法正常退出而死亡,或者因?yàn)闆](méi)有捕獲的異常終止了run方法而死亡。

一個(gè)調(diào)用了某個(gè)對(duì)象的 Object.wait() 方法的線程會(huì)等待另一個(gè)線程調(diào)用此對(duì)象Object.notify()方法 或 Object.notifyAll()方法。

其實(shí)waiting狀態(tài)并不是一個(gè)線程的操作,它體現(xiàn)的是多個(gè)線程間的通信,可以理解為多個(gè)線程之間的協(xié)作關(guān)系, 多個(gè)線程會(huì)爭(zhēng)取鎖,同時(shí)相互之間又存在協(xié)作關(guān)系。

當(dāng)多個(gè)線程協(xié)作時(shí),比如A,B線程,如果A線程在Runnable(可運(yùn)行)狀態(tài)中調(diào)用了wait()方法那么A線程就進(jìn)入 了Waiting(無(wú)限等待)狀態(tài),同時(shí)失去了同步鎖。假如這個(gè)時(shí)候B線程獲取到了同步鎖,在運(yùn)行狀態(tài)中調(diào)用了 notify()方法,那么就會(huì)將無(wú)限等待的A線程喚醒。注意是喚醒,如果獲取到鎖對(duì)象,那么A線程喚醒后就進(jìn)入 Runnable(可運(yùn)行)狀態(tài);如果沒(méi)有獲取鎖對(duì)象,那么就進(jìn)入到Blocked(鎖阻塞狀態(tài))。

public class WaitAndSleep {
  public static void main(String[] args) {
    //創(chuàng)建鎖對(duì)象
    Object lock = new Object();

    //匿名內(nèi)部類創(chuàng)建線程1
    new Thread(){
      @Override
      public void run() {
        System.out.println(Thread.currentThread().getName()+"需要買票");
        //用同步代碼塊包裹
        synchronized (lock){
          try {
            //lock.wait(5000);//到5秒自動(dòng)醒來(lái)
            lock.wait();//進(jìn)入無(wú)限等待,需要喚醒
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        System.out.println(Thread.currentThread().getName()+"買到了票");
      }
    }.start();

    //匿名內(nèi)部類創(chuàng)建線程2
    new Thread(){
      @Override
      public void run() {
        try {
          Thread.sleep(5000);//等待5秒
          System.out.println(Thread.currentThread().getName()+"出票了");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        //用同步代碼塊包裹
        synchronized (lock){
          lock.notify();//如果有多個(gè)線程等待,隨機(jī)喚醒一個(gè)
          //lock.notifyAll();//喚醒所有等待的線程
        }
      }
    }.start();
  }
}

線程池

當(dāng)在系統(tǒng)中用到了很多的線程,大量的啟動(dòng)和結(jié)束動(dòng)作會(huì)導(dǎo)致系統(tǒng)的性能變卡,響應(yīng)變慢,采用線程池可以解決這個(gè)問(wèn)題。線程池就相當(dāng)于一個(gè)容器(如同ArrayList),執(zhí)行的任務(wù)放入線程池中,多出來(lái)的任務(wù)就等待線程池中的任務(wù)執(zhí)行完再放入。

  • 使用線程池的工廠類 Executors 里的靜態(tài)方法 newFixedThreadPool 生產(chǎn)指定線程數(shù)量的線程池,返回為ExecutorService接口
  • 創(chuàng)建一個(gè)類實(shí)現(xiàn)Runnable接口,重寫(xiě)run方法,設(shè)置線程任務(wù)
  • 調(diào)用ExecutorService中的submit方法,傳遞線程任務(wù),開(kāi)啟線程
  • 銷毀線程池:ExecutorService中的shutdown方法
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//線程池
public class ThreadPoolMain {
  public static void main(String[] args) {
    //使用線程池的工廠類 Executors里的靜態(tài)方法 newFixedThreadPool
    // 生產(chǎn)指定線程數(shù)量的線程池,返回為ExecutorService接口
    ExecutorService es = Executors.newFixedThreadPool(2);

    //調(diào)用ExecutorService中的submit方法,傳遞線程任務(wù),開(kāi)啟線程
    es.submit(new ThreadPoolDemo01());
  }
}

//////////////////////////////////////////////////////

//創(chuàng)建一個(gè)類實(shí)現(xiàn)Runnable接口,重寫(xiě)run方法,設(shè)置線程任務(wù)
public class ThreadPoolDemo01 implements Runnable{
  @Override
  public void run() {
    ...
  }
}

以上就是JAVA多線程知識(shí)匯總的詳細(xì)內(nèi)容,更多關(guān)于JAVA多線程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java對(duì)象不使用時(shí)賦值null的意義詳解

    Java對(duì)象不使用時(shí)賦值null的意義詳解

    這篇文章主要介紹了java對(duì)象不再使用時(shí)賦值null的意義,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java對(duì)接支付寶支付接口簡(jiǎn)單步驟記錄

    java對(duì)接支付寶支付接口簡(jiǎn)單步驟記錄

    最近項(xiàng)目APP需要接入微信、支付寶支付功能,在分配開(kāi)發(fā)任務(wù)時(shí),聽(tīng)說(shuō)微信支付接口比支付寶支付接口要難實(shí)現(xiàn),這篇文章主要給大家介紹了關(guān)于java對(duì)接支付寶支付接口的簡(jiǎn)單步驟,需要的朋友可以參考下
    2024-05-05
  • Java實(shí)現(xiàn)時(shí)間與字符串互相轉(zhuǎn)換詳解

    Java實(shí)現(xiàn)時(shí)間與字符串互相轉(zhuǎn)換詳解

    這篇文章主要為大家詳細(xì)介紹了Java中實(shí)現(xiàn)時(shí)間與字符串互相轉(zhuǎn)換的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • Java實(shí)現(xiàn)拓?fù)渑判虻氖纠a

    Java實(shí)現(xiàn)拓?fù)渑判虻氖纠a

    這篇文章我們要講的是拓?fù)渑判颍@是一個(gè)針對(duì)有向無(wú)環(huán)圖的算法,主要是為了解決前驅(qū)后繼的關(guān)系,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-05-05
  • idea本地merge如何合并代碼

    idea本地merge如何合并代碼

    這篇文章主要介紹了idea本地merge如何合并代碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java源碼跟蹤閱讀技巧【值得收藏】

    Java源碼跟蹤閱讀技巧【值得收藏】

    今天跟大家分享一下我平時(shí)閱讀源碼的幾個(gè)小技巧,對(duì)于閱讀Java中間件如Spring、Dubbo等框架源碼的同學(xué)有一定幫助。本文基于Eclipse IDE,感興趣的朋友跟隨小編一起看看吧
    2018-11-11
  • Java數(shù)據(jù)結(jié)構(gòu)-HashMap詳解

    Java數(shù)據(jù)結(jié)構(gòu)-HashMap詳解

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)-HashMap,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java實(shí)現(xiàn)判斷瀏覽器版本與類型簡(jiǎn)單代碼示例

    Java實(shí)現(xiàn)判斷瀏覽器版本與類型簡(jiǎn)單代碼示例

    這篇文章主要介紹了Java實(shí)現(xiàn)判斷瀏覽器版本與類型簡(jiǎn)單代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • hibernate 配置數(shù)據(jù)庫(kù)方言的實(shí)現(xiàn)方法

    hibernate 配置數(shù)據(jù)庫(kù)方言的實(shí)現(xiàn)方法

    這篇文章主要介紹了hibernate 配置數(shù)據(jù)庫(kù)方言的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • Java8新特性之空指針異常的克星Optional類的實(shí)現(xiàn)

    Java8新特性之空指針異常的克星Optional類的實(shí)現(xiàn)

    這篇文章主要介紹了Java8新特性之空指針異常的克星Optional類的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10

最新評(píng)論

阜宁县| 六枝特区| 三台县| 南阳市| 昌吉市| 阳城县| 灵璧县| 青河县| 咸宁市| 武陟县| 留坝县| 托克逊县| 江安县| 中阳县| 宁都县| 巴楚县| 龙游县| 南通市| 孝感市| 呼伦贝尔市| 麟游县| 西乌珠穆沁旗| 泰和县| 克东县| 惠安县| 万年县| 平江县| 孝昌县| 林口县| 盘锦市| 竹山县| 密山市| 建湖县| 边坝县| 平果县| 新乡市| 那曲县| 额尔古纳市| 梁平县| 德兴市| 鄢陵县|