溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java多線程的原理及用法

發布時間:2021-07-05 18:35:12 來源:億速云 閱讀:169 作者:chen 欄目:開發技術

這篇文章主要介紹“java多線程的原理及用法”,在日常操作中,相信很多人在java多線程的原理及用法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java多線程的原理及用法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

目錄
  • 一、線程的生命周期

    • JDK中用Thread.State類定義了線程的幾種狀態:

  • 二、線程同步

    • 1、為什么要有線程同步

    • 2、synchronized

      • 2.1同步代碼塊

      • 2.2同步方法

    • 3、Lock鎖

一、線程的生命周期

JDK中用Thread.State類定義了線程的幾種狀態:

要想實現多線程,必須在主線程中創建新的線程對象。Java語言使用 Thread類及其子類的對象來表示線程,在它的一個完整的生命周期中通常 要經歷如下的五種狀態:

  • 新建:當一個Thread類或其子類的對象被聲明并創建時,新生的線程 對象處于新建狀態;

  • 就緒:處于新建狀態的線程被start()后,將進入線程隊列等待CPU時間 片,此時它已具備了運行的條件,只是沒分配到CPU資源;

  • 運行:當就緒的線程被調度并獲得CPU資源時,便進入運行狀態, run()方法定義了線程的操作和功能;

  • 阻塞:在某種特殊情況下,被人為掛起或執行輸入輸出操作時,讓出 CPU 并臨時中止自己的執行,進入阻塞狀態;

  • 死亡:線程完成了它的全部工作或線程被提前強制性地中止或出現異常 導致結束。 在上面五個階段中,只有新建和死亡是不可重復,其它幾個狀態都可能改變。

java多線程的原理及用法

注意:

1.新建和死亡狀態只能有一次;

2.運行狀態只能是從就緒狀態變過來的;

3.阻塞狀態不能直接變為運行狀態,需要通過就緒狀態;

4.當一個運行狀態的線程調用yield()方法后,就會變為就緒狀態;

5.當一個運行狀態的線程調用sleep()、等待同步鎖方法、wait()方法或 join()方法時,就會處理阻塞狀態;

6.當一個阻塞狀態的線程調用notify()/notifyAll()方法,或者sleep()方法 結束,再或者獲得同步鎖,或者join()線程執行完畢就可以變為就緒狀 態的線程

7.當一個線程執行過多后就處理死亡狀態,即線程生命周期結束。

二、線程同步

1、為什么要有線程同步

為了解決線程安全問題,在多線程下,多個線程對一個數據進行修改時,可能會產生數據出錯的問題,所以我們就需要通過線程同步的方法來解決問題。

Java中的線程同步實現方式:

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();
                }
            }
        }

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

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();
            }
        }
    }

**注意:**當使用同步方法來處理多線程的共享數據問題,如果是靜態方法,使用的是類名.class方式,如果是非靜態方法,使用的是this。

3、Lock鎖

使用Lock.lock()進行加鎖操作,然后使用Lock.unlock()方法來進行 解鎖。

Lock是一個接口,不能直接實例化,需要使用子類來實例化,通常使用的 子類是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()方法來作加鎖處 理;在同步操作的代碼塊之后,增加finally語句塊來釋放鎖,釋放鎖的方法為Lock.unlock()方法;一定要確保鎖能釋放,否則就是死鎖;

Lock比synchronized更輕量級,功能更強大,如果可以盡量使用Lock。

到此,關于“java多線程的原理及用法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女