一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - JAVA多線程知識匯總

JAVA多線程知識匯總

2020-07-30 15:01擱淺Lee Java教程

這篇文章主要介紹了JAVA多線程的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

線程概念

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

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

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

線程調(diào)度:

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

創(chuàng)建多線程

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

  • 創(chuàng)建Thread類的子類,并重寫該類的run()方法,設(shè)置線程任務(wù)。
  • 創(chuàng)建Thread子類的實例,即創(chuàng)建了線程對象
  • 調(diào)用線程對象的start()方法來啟動該線程
?
1
2
3
4
5
6
7
8
9
10
//方法一:
//定義Thread類的子類,并重寫該類的run()方法
public class MyThreadDemo01 extends Thread {
  @Override
  public void run() {
    for (int i = 0; i < 20 ; i++) {
      System.out.println(getName()+"-->"+i);
    }
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//主線程
public class MainThread01 {
  public static void main(String[] args) {
    //創(chuàng)建Thread子類的實例,即創(chuàng)建了線程對象
    MyThreadDemo01 thread01 = new MyThreadDemo01();
 
    //調(diào)用線程對象的start()方法來啟動該線程
    thread01.start();
 
    for (int i = 0; i < 10 ; i++) {
      System.out.println(Thread.currentThread().getName()+"-->"+i);
    }
  }
}

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

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

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

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

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

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

  • 定義Runnable接口的實現(xiàn)類,并重寫該接口的run()方法,設(shè)置線程任務(wù)
  • 創(chuàng)建Runnable實現(xiàn)類對象
  • 創(chuàng)建Thread類的對象,并且該對象構(gòu)造方法中傳遞Runnable實現(xiàn)類對象
  • 調(diào)用Thread對象的start()方法來啟動線程
?
1
2
3
4
5
6
7
8
9
10
//方法二:
//定義Runnable接口的實現(xiàn)類,并重寫該接口的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);
    }
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//主線程
public class MainThread {
  public static void main(String[] args) { 
    //創(chuàng)建Runnable實現(xiàn)類對象
    MyThreadDemo02 runnable = new MyThreadDemo02();
 
    //創(chuàng)建Thread類的對象,并且該對象構(gòu)造方法中傳遞Runnable實現(xiàn)類對象
    Thread thread02 = new Thread(runnable);
 
    //調(diào)用Thread對象的start()方法來啟動線程
    thread02.start();
 
    for (int i = 0; i < 20 ; i++) {
      System.out.println(Thread.currentThread().getName()+"-->"+i);
    }
  }
}

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

  • 匿名內(nèi)部類能夠簡化程序
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//方法三:匿名內(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);
    }
  }
}

線程安全問題

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

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

解決線程安全問題采用線程同步機制,主要有以下三種方式:

  • 同步代碼塊
  • 同步方法
  • 鎖機制

同步代碼塊

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

  • 格式:synchronized(鎖對象){ //訪問共享數(shù)據(jù)的代碼 }
  • 鎖對象可以是任意類型
  • 多個線程對象要使用同一把鎖
  • 鎖對象是將同步代碼塊鎖住,只讓線程在同步代碼塊中執(zhí)行
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class SafeRunnableDemo implements Runnable {
  private int ticket = 100;
 
  //同步代碼塊
  //創(chuàng)建鎖對象
  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í)行該方法的時候,其他線程只能在方法外等著

  • 格式:修飾符 synchronized 返回值類型 方法名(參數(shù)列表) { //訪問共享數(shù)據(jù)的代碼 }
  • 把共享了同步數(shù)據(jù)的代碼抽取出來,放入同步方法中
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class SafeRunnableDemo implements Runnable {
  private int ticket = 100;
 
  //同步方法
  //定義一個同步方法
  public synchronized void lock(){
    //同步方法鎖住代碼塊
    if (ticket > 0) {
      System.out.println(Thread.currentThread().getName() + "正在賣第" + ticket + "張");
      ticket--;
    }
  }
 
  //重寫run并使用同步方法
  @Override
  public void run() {
    while (true){
      lock();
    }
  }
}

Lock鎖

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

  • 在Lock接口中 void lock() 獲取鎖,void unlock() 釋放鎖
  • 需要在成員位置處創(chuàng)建ReentraLock對象,在共享數(shù)據(jù)代碼塊之前調(diào)用方法lock()獲取鎖,在之后用unlock()方法釋放鎖
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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對象
  Lock lock = new ReentrantLock();
  @Override
  public void run() {
    while (true){
      //在可能出現(xiàn)問題的代碼塊之前用lock()方法
      lock.lock();
      if (ticket > 0) {
        System.out.println(Thread.currentThread().getName() + "正在賣第" + ticket + "張");
        ticket--;
      }
      //在可能出現(xiàn)問題的代碼塊之后用unlock()方法
      lock.unlock();
    }
  }
}

線程機制

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class WaitAndSleep {
  public static void main(String[] args) {
    //創(chuàng)建鎖對象
    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秒自動醒來
            lock.wait();//進(jìn)入無限等待,需要喚醒
          } 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();//如果有多個線程等待,隨機喚醒一個
          //lock.notifyAll();//喚醒所有等待的線程
        }
      }
    }.start();
  }
}

線程池

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

  • 使用線程池的工廠類 Executors 里的靜態(tài)方法 newFixedThreadPool 生產(chǎn)指定線程數(shù)量的線程池,返回為ExecutorService接口
  • 創(chuàng)建一個類實現(xiàn)Runnable接口,重寫run方法,設(shè)置線程任務(wù)
  • 調(diào)用ExecutorService中的submit方法,傳遞線程任務(wù),開啟線程
  • 銷毀線程池:ExecutorService中的shutdown方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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ù),開啟線程
    es.submit(new ThreadPoolDemo01());
  }
}
 
//////////////////////////////////////////////////////
 
//創(chuàng)建一個類實現(xiàn)Runnable接口,重寫run方法,設(shè)置線程任務(wù)
public class ThreadPoolDemo01 implements Runnable{
  @Override
  public void run() {
    ...
  }
}

以上就是JAVA多線程知識匯總的詳細(xì)內(nèi)容,更多關(guān)于JAVA多線程的資料請關(guān)注服務(wù)器之家其它相關(guān)文章!

原文鏈接:https://www.cnblogs.com/geqianLee/p/13268370.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品视频久久久久 | 欧美一级特黄特色大片免费 | 羞羞视频麻豆 | 97影院手机版 | oneday日本在线观看完整版 | 日本老师xxxxx18 | 高h文恩好大好爽 | 纲手被comic天堂 | 星空无限传媒视频在线观看视频 | 湖南美女被黑人4p到惨叫 | 男女激情网 | 国产精品成| 国产好痛疼轻点好爽的视频 | 精品国产美女福利在线 | 91精品国产免费久久 | 日韩精品一区二区三区中文在线 | 欧美男同猛男 videos 同性 | 国产午夜精品理论片 | 91精品啪在线观看国产91九色 | 亚洲男人天堂影院 | 精品日韩欧美一区二区三区 | yy8090韩国日本三理论免费 | 处女私拍 | 精品亚洲综合久久中文字幕 | 国产麻豆在线观看网站 | 欧美肥胖bb | 美女撒尿无遮挡免费中国 | 423hk四虎 | 国产精品久久久久久岛国 | 俺去俺来也在线www色官网 | 亚洲精品免费在线观看 | 欧美大奶艳星 | 全是女性放屁角色的手游 | 男女男精品视频 | 欧美人妖另类性hd | 11 13加污女qq看他下面 | 国产亚洲精品高清在线 | julianann办公室 | 皇上撞着太子妃的秘密小说 | 我的年轻漂亮继坶三级 | 欧美18-19sex性处 |