1. 程式人生 > >【多執行緒程式設計】認識死鎖

【多執行緒程式設計】認識死鎖

死鎖

死鎖是指兩個或兩個以上的程序在執行過程中,
由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,
若無外力作用,它們都將無法推進下去。
此時稱系統處於死鎖狀態或系統產生了死鎖,
這些永遠在互相等待的程序稱為死鎖程序。

手動寫死鎖程式碼

public class DeadLock {
    private static Object a = new Object();
    private static Object  b= new Object();

    public static void main(String[] args) {
      new Thread(){
          @Override
          public void run() {
              synchronized (a){
                  System.out.println("a lock");
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }

                  synchronized (b){
                      System.out.println("b lock");
                  }
              }
          }
      }.start();


        new Thread(){
            @Override
            public void run() {
                synchronized (b){
                    System.out.println("b lock");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (a){
                        System.out.println("a lock");
                    }
                }
            }
        }.start();
    }
}

輸出

  a lock
  b lock

兩個執行緒相互得到鎖a、鎖b,然後執行緒1等待執行緒2釋放鎖b,而執行緒2等待執行緒1釋放鎖a,兩者互不相讓,如果沒有外力作用,則會形成死鎖。

死鎖的解決辦法

1、按順序加鎖

       上個列子就是兩個執行緒加鎖的順序不一致,導致死鎖,如果每個執行緒都按一個順序加鎖,就不會出現死鎖。

public class DeadLock {
    private static Object a = new Object();
    private static Object  b= new Object();

    public static void main(String[] args) {
      new Thread(){
          @Override
          public void run() {
              synchronized (a){
                  System.out.println("a lock");
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }

                  synchronized (b){
                      System.out.println("b lock");
                  }
              }
          }
      }.start();


        new Thread(){
            @Override
            public void run() {
                synchronized (a){
                    System.out.println("a lock");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (b){
                        System.out.println("b lock");
                    }
                }
            }
        }.start();
    }
}

輸出

  a lock
  b lock
  a lock
  b lock

2、獲取鎖時限

       如果每個執行緒在索取鎖的時候,都加上個時限,如果超過這個時間,就放棄鎖,就不會產生死鎖。

3、死鎖檢測

      死鎖檢測是一個更好的死鎖預防機制,它主要是針對那些不可能實現按序加鎖並且鎖超時也不可行的場景。

      根據執行緒間獲取鎖的關係檢測執行緒間會不會發生死鎖,如果會發生死鎖,則執行一定的策略,比如中斷執行緒,回滾操作。

相關推薦

執行程式設計認識

死鎖 死鎖是指兩個或兩個以上的程序在執行過程中, 由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象, 若無外力作用,它們都將無法推進下去。 此時稱系統處於死鎖狀態或系統產生了死鎖, 這些永遠在互相等待的程序稱為死鎖程序。 手動寫死鎖程式碼 public class D

執行程式設計 synchronized全域性和例項的區別

例項鎖 -- 鎖在某一個例項物件上。如果該類是單例,那麼該鎖也具有全域性鎖的概念。                例項鎖對應的就是synchronized關鍵字。全域性鎖 -- 該鎖針對的是類,無論例項多少個物件,那麼執行緒都共享該鎖。                全域性鎖

執行程式設計執行私有資料(TSD)

Thread Specific Data(TSD) 執行緒私有資料,有什麼用呢?在多執行緒中,經常要用全域性變數來實現多個函式間的資料共享。由於資料空間是共享的,因此全域性變數也為所有程序共有。但有時應用程式設計中必要提供執行緒私有的全域性變數,這個變數被各個執行緒私有,但

Linux C 執行程式設計互斥與條件變數

一、互斥鎖互斥量從本質上說就是一把鎖, 提供對共享資源的保護訪問。  1. 初始化:  在Linux下, 執行緒的互斥量資料型別是pthread_mutex_t. 在使用前, 要對它進行初始化:  對於靜態分配的互斥量, 可以把它設定為PTHREAD_MUTEX_INITIA

java執行程式設計三種執行的實現方式

文章目錄 前言 程序與執行緒 繼承Thread類,實現多執行緒 FAQ 為什麼多執行緒的啟動不直接使用run()方法而必須使用Thread類中start()方法呢? 基於Runnable介面實現多執行緒 Thread 與

方格取數執行DP&傳紙條執行DP

題目: 設有N*N的方格圖(N<=10,我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。如下圖所示(見樣例): 某人從圖的左上角的A 點出發,可以向下行走,也可以向右走,直到到達右下角的B點。在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字0)。

執行系列future模式

package com.daojia.future; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.

java執行程式設計之讀寫設計高效能快取器

解決多執行緒執行緒安全問題的主要方法是通過加鎖的方式來實現,當多個執行緒對某個變數進行讀取或寫入的時候通過加鎖來限定只有當前獲取鎖許可權的執行緒才可以對資料進行讀寫,當該執行緒訪問完畢釋放鎖之後其他阻

入坑JAVA執行併發(六)

  在多執行緒的中,因為要保證執行緒安全,需要對一些操作進行加鎖,但是如果操作不當,會造成死鎖,導致程式無法執行下去。   形成死鎖的場景:如果有兩個執行緒,執行緒1和執行緒2,執行緒1執行,獲得鎖A,執行緒2執行,獲得B,執行緒1等待鎖B的釋放,執行緒2等待

Java執行執行(九)——

Java中的死鎖指的就是一種多於兩個執行緒永遠阻塞的特殊狀況。Java中的死鎖狀態至少需要多於兩個執行緒以及資源的時候才會產生。這裡,我寫了一個產生死鎖的程式,並且講下如何分析死鎖。 首先來看一下產生死鎖的程式: package com.sapphire

python執行程式設計(3): 使用互斥同步執行

問題的提出 上一節的例子中,每個執行緒互相獨立,相互之間沒有任何關係。現在假設這樣一個例子:有一個全域性的計數num,每個執行緒獲取這個全域性的計數,根據num進行一些處理,然後將num加1。很容易寫出這樣的程式碼: # encoding: UTF-8import

Java執行程式設計核心技術第一章(執行技能suspend,resume,yield)

1.8 暫停執行緒      在多執行緒中,suspend是暫停執行緒,resume是恢復執行緒的執行.  1.8.1suspend方法和resume方法的使用 public class MyThread extends Thread { private lon

Java執行程式設計核心技術第一章(執行技能 執行的優先順序)

1.8 執行緒的優先順序  在作業系統中,執行緒可以劃分優先順序,優先順序較高的執行緒得到的cpu的資源較多,也就是cpu優先執行優先順序較高的執行緒物件中的任務.  在Java中,執行緒優先順序分為1~10個等級,如果小於1大於10,則JDK丟擲異常,原始碼如下:

java執行程式設計歷史演變截止到jdk8

最近看了咕泡學視訊教程,這裡算是做一個記錄。 一、JDK1.5之前時代 建立執行緒的方式 繼承thread package study.java5; /** * @Auther: zhw * @D

新聞本人新書《Java執行程式設計實戰指南(核心篇)》已出版上市

豆瓣主頁 購買連結 試讀下載 (待補充) 原始碼下載 內容簡介 隨著現代處理器的生產工藝從提升處理器主頻頻率轉向多核化,即在一塊晶片上整合多個處理器核心(Core),多核處理器(Multicore Proc

專欄 - Java 執行程式設計

Java 多執行緒程式設計 Java多執行緒程式設計,是併發程式設計的一種(另一種重要的併發程式設計是多程序程式設計)。我們寫java程式一般是執行在同一個程序中的,所以可以簡單的認為:併發程式設計 = 多執行緒程式設計,讓寫作業

C++執行程式設計學習(1)-CPU個數、CPU核心數、CPU執行

轉自:CPU個數、CPU核心數、CPU執行緒數(by kimsimple)   CPU個數即CPU晶片個數。 CPU核心數是指物理上,也就是硬體上存在著幾個核心。比如,雙核就是包括2個相對獨立的CPU核心單元組,四核就包含4個相對獨立的CPU核心單元組。 CPU執行緒數是一

python核心程式設計-練習| 執行程式設計

1. 程序與執行緒。執行緒與程序的區別是什麼? 什麼是程式? 計算機程式只不過是磁碟中可執行的,二進位制(或其它型別)的資料。程式是靜態的,可修改的檔案資料; 什麼是程序? 程序是程式被讀取到記憶體中,被作業系統呼叫的時候程式的一次執行過程

Java執行程式設計核心技術第四章 Lock的使用

使用ReentrantLock類 Lock lock = new ReentrantLock(); lock.lock(); //同步的程式碼段 ... lock.unlock(); Condition用法:await(), signal()方法呼叫之前需要呼叫lock.loc

Java執行程式設計核心技術第三章 執行間通訊

等待/通知機制 public final native void wait(long timeout) throws InterruptedException; /* @throws IllegalMonitorStateException if the current th