這是在呼叫list的addrange方法時,遇到「system.argumentexception: 目標陣列的長度不夠。請檢查 destindex 和長度以及陣列的下限。」的問題。
初步估計是執行緒安全的問題。
覺得它對這個問題的分析相對獨特,故轉過來了。
system.argumentexception: 目標陣列的長度不夠。請檢查 destindex 和長度以及陣列的下限。
在 system.array.copy(array sourcearray, int32 sourceindex, array destinationarray, int32 destinationindex, int32 length, boolean reliable)
在 system.array.copy(array sourcearray, int32 sourceindex, array destinationarray, int32 destinationindex, int32 length)
在 system.collections.generic.list`1.toarray()
這是怎麼回事?
這裡說說怎麼避免這問題出現。
因為之前沒有大量的對list的測試,也不知道,list是否執行緒安全的。當然執行緒安全的,
總得要有同步操作。這裡肯定就會耗效能了。
list.toarray()出異常了? 我想:出於效能考慮,.net 的list.toarray()內的操作沒有加鎖同步處理。
如下**解說:
c# code
? 1
2
3
4
5
6
public
t toarray()
以上**是用.net refelctor 反編譯的。list.toarray()方法內的**。
果然是沒有加lock或是其它的同步操作。
原因:有兩操作a,b,分別非同步的操作了乙個.add(t item)或是.remove(t item)方法別乙個list的.toarray()。
然後,在第乙個先操作的,指令在時間片上,佔第一位。
c# code
? 1
2
3
4
5
6
7
8
9
public
void
add(t item)
this
._items[
this
._size++] = item;
this
._version++;
}
從上面來看,add(t item)也是沒有加同步鎖的
if (this._size == this._items.length)//a的
假設:緊跟著下一條執行的指令應該是:
t destinationarray = new t[this._size];//b的
但,由於非同步操作。
然後,在第二個操作的時候,因為是非同步的,所以有可能在第乙個操作的指令
緊跟著要執行的指定就成了第二個操作的第乙個指令,依此類推下去,將所有執行順序的列出來
//假設:執行前,this.count == 10
if (this._size == this._items.length)//a的
this.ensurecapacity(this._size + 1);//a的
t destinationarray = new t[this._size];//b的 假設計this.count = 10
this._items[this._size++] = item;//a的,這時,this.count == 11了
array.copy(this._items, 0, destinationarray, 0, this._size);
//b的,這時,所有this.count == 1,而剛定義的destinationarray.length == 10的,
//所以這時,一旦執行copy就會出下限不足的異常。
所以,現在我們知道了list不是執行緒安全的,很多時候,我們都必須自己要對list的操作前,加個鎖,同步一下。
例如:正常**:
c# code
? 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class
testclass{}
static
listtestclasslist =
new
list();
static
void
main()
}
void
threadmethod()
異常**:
c# code
? 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class
testclass{}
static
listtestclasslist =
new
list();
static
void
main()
}
void
threadmethod()
}
多執行緒例項呼叫同步方法
針對執行緒同步,做了個小例子。1.多執行緒例項化多個物件,呼叫同步方法 2.多執行緒通過單例,呼叫同步方法 public class mytest 單例物件不被建立 public static mytest mytest null 方便測試,就不寫 public static void main s...
C 將List資料分執行緒同步呼叫
最近公司專案需要,要進行多執行緒進行耗時,特意寫了個多用途泛型類,以供後續使用 public class autorunthread public void starttask k action allcompletetask null where k runthreadbase new ttt.p...
執行緒同步問題
昨天簡單研究了一點執行緒的同步問題 package com.pb.thread public class waymakethread 建立乙個執行緒,繼承thread類 class mythread extends thread 建立乙個類,實現runable介面,這不是乙個執行緒類 class m...