1. 程式人生 > >【Java】四個執行緒訪問同一陣列並作出相應修改

【Java】四個執行緒訪問同一陣列並作出相應修改

需求是開四個執行緒訪問一個Vector(因為Vector是執行緒安全的),取得Vector的資訊,這個資訊是要一段時間進行處理,就是說,取得資訊訪問之後,可能這個資訊還沒有處理完,所以要先等一等,先取得取得Vector下一個元素再訪問。

現在我遇上的問題是

  1. 怎麼在開四個執行緒的時候,保持Vector的共同性,就是在一個執行緒取得資訊之後,成功處理,讓其他三個不要再訪問當前元素了。

  2. 四個執行緒怎麼按照順序完成對Vector的每個元素的訪問。

初次嘗試
1. 因為Java引用的存在,所以在每個執行緒裡修改是可以見的,但是要加volatile修飾,否則只會在當前執行緒中的工作區可見,而不能到所有執行緒的工作區。

  1. 可以用哲學家演算法,為一條資訊增加一個boolean判斷值,如果有執行緒正在訪問就修改該boolean判斷值為1,再結束訪問之後,修改會0。在裡面並不關心順序問題,只要所有資訊被處理就好了。Vector是執行緒安全的ArrayList所以也可以用下標訪問,所以我的迴圈條件就是
    while(true){
        while(true){
        如果當前指向的陣列正在被訪問 指向的位置向前一步,如果超出了Vector的範圍取模
        如果當前指向的陣列沒有被訪問 跳出當前的死迴圈

        如果當前所有的陣列資訊都被訪問到了 結束這個執行緒
}

        取得對應Vector的資訊
        發往Url處理
        根據結果 判斷是否成功還是未處理完
            成功或失敗 分別放入對應的地方
            未處理完 繼續下一個迴圈
        }

二改
應該講狀態陣列和資料處理兩件事分成兩部分,而不是混在一個執行緒裡完成,所以說我們需要在這個執行緒中獲得返回值,所以應該使用Callable。並且多執行緒的操作可以使用Java裡的ConCurrent包來完成。

這裡要使用的ThreadPoolExecutor submit操作來獲取執行緒執行的結果 所以我的設計是這樣的

while(true){
    判斷 是否所有的資訊都被處理 成功和失敗的結果集相加=TaskId的Size 
        處理完跳出迴圈
    //因為我開的是固定四個執行緒的執行緒池

    for1->4){
        result = ThreadPoolExecutor.submit(index
); 判斷result 結果 加入相應的結果集 index = (index+1)%Size } }

理論上這一步並沒有多少IO操作,並且數目不大的情況下影響並不大,所以單執行緒跑一個迴圈即可。
emmmmmmm