JAVA教程第六講Java的線程和JavaApplet6.2

字號:

6.2多線程的互斥與同步
    臨界資源問題
    前面所提到的線程都是獨立的,而且異步執(zhí)行,也就是說每個線程都包含了運行時所需要的數(shù)據(jù)或方法,而不需要外部的資源或方法,也不必關(guān)心其它線程的狀態(tài)或行為。但是經(jīng)常有一些同時運行的線程需要共享數(shù)據(jù),此時就需考慮其他線程的狀態(tài)和行為,否則就不能保證程序的運行結(jié)果的正確性。例6.4說明了此問題。
    例6.4
    class stack{
    int idx=0; //堆棧指針的初始值為0
    char[ ] data = new char[6]; //堆棧有6個字符的空間
    public void push(char c){ //壓棧操作
     data[idx] = c; //數(shù)據(jù)入棧
     idx + +; //指針向上移動一位
    }
    public char pop(){ //出棧操作
      idx - -; //指針向下移動一位
      return data[idx]; //數(shù)據(jù)出棧
    }
    }
    兩個線程A和B在同時使用Stack的同一個實例對象,A正在往堆棧里push一個數(shù)據(jù),B則要從堆棧中pop一個數(shù)據(jù)。如果由于線程A和B在對Stack對象的操作上的不完整性,會導(dǎo)致操作的失敗,具體過程如下所示:
    1) 操作之前
    data = | p | q | | | | | idx=2
    2) A執(zhí)行push中的第一個語句,將r推入堆棧;
    data = | p | q | r | | | | idx=2
    3) A還未執(zhí)行idx++語句,A的執(zhí)行被B中斷,B執(zhí)行pop方法,返回q:
    data = | p | q | r | | | | idx=1
    4〕A繼續(xù)執(zhí)行push的第二個語句:
    data = | p | q | r | | , | | idx=2
    最后的結(jié)果相當于r沒有入棧。產(chǎn)生這種問題的原因在于對共享數(shù)據(jù)訪問的操作的不完整性。