Test conditions:
Open 2 parallel execution tasks to write values to the same list object
Test code:
Static intMaxnum =1000000; Staticlist<int> list =Newlist<int>(); Static voidMain (string[] args) { //Number of iterations intIterationnum =3; Codetimer.initialize (); Codetimer.time ("is the list thread-safe? ", Iterationnum,NewAction (Lististhreadsafe)); //Console.Write (sbisthreadsafe.tostring ());Console.read (); } Private Static voidLististhreadsafe () {Parallel.For (1, Maxnum/2, (i) = ={list. ADD (i); }); Parallel.For (Maxnum/2+1, Maxnum, (i) = ={list. ADD (i); }); }
View Code
Test results:
Test conclusion:
This result is caused because the list object is not thread safe. What should we do then?
At this point we need to use the type under the System.Collections.Concurrent namespace for the parallel loop body.
Class |
Description |
Blockingcollection<t> |
To implement thread safety for iproducerconsumercollection<t> Collection provides throttling and throttling capabilities. |
Concurrentbag<t> |
Represents an unordered collection of thread-safe objects. |
Concurrentdictionary<tkey, tvalue> |
Represents a thread-safe collection of key-value pairs that can be accessed concurrently by multiple threads. |
Concurrentqueue<t> |
Represents a thread-safe FIFO (FIFO) collection. |
Concurrentstack<t> |
Represents a thread-safe last-in-first-out (LIFO) collection. |
Orderablepartitioner<tsource> |
Represents a specific way to split a sortable data source into multiple partitions. |
Partitioner |
Provides common partitioning policies for arrays, lists, and enumerable items. |
Partitioner<tsource> |
Represents a specific way to split a data source into multiple partitions. |
Let's do another test.
Test code:
Static intMaxnum =1000000; Staticconcurrentqueue<int> safelist =Newconcurrentqueue<int>(); Static voidMain (string[] args) { //Number of iterations intIterationnum =3; Codetimer.initialize (); Codetimer.time ("is concurrentqueue thread-safe? ", Iterationnum,NewAction (Lististhreadsafe)); //Console.Write (sbisthreadsafe.tostring ());Console.read (); } Private Static voidLististhreadsafe () {Parallel.For (1, Maxnum/2, (i) = ={safelist.enqueue (i); }); Parallel.For (Maxnum/2+1, Maxnum, (i) = ={safelist.enqueue (i); }); }
View Code
Test results:
Test conclusion:
Concurrentqueue is thread-safe. You should use Concurrentqueue instead of list when encountering multi-threading and parallel development.
Question: In order to ensure the object thread security, the system underlying implementation mechanism must be to use the object lock and unlock function to ensure that the object security, then lock and unlock will affect the performance?
Let's take another set of tests:
Test conditions:
(1) A normal cyclic operation of 1 million data is then added to the List collection object.
(2) A parallel loop operation of 1 million data is then added to the Concurrentqueue collection object.
Test code:
Static intMaxnum =1000000; Staticlist<biginteger> list =NewList<biginteger>(); StaticConcurrentqueue<biginteger> safelist =NewConcurrentqueue<biginteger>(); Static voidMain (string[] args) { //Number of iterations intIterationnum =3; Codetimer.initialize (); Codetimer.time ("Normal cyclic operations", Iterationnum,NewAction (Normalcompute)); Codetimer.time ("Parallel loop Operation _1", Iterationnum,NewAction (parallelcompute_1)); Codetimer.time ("Parallel loop Operation _2", Iterationnum,NewAction (parallelcompute_2)); Console.read (); } Private Static voidNormalcompute () { for(inti =1; I <= maxnum; i++) {Math.pow (I, I+1); List. ADD (NewBigInteger (i)); } } Private Static voidparallelcompute_1 () {Parallel.For (1, Maxnum, (i) = ={Math.pow (i, I+1); Safelist.enqueue (NewBigInteger (i)); }); } Private Static voidparallelcompute_2 () {Parallel.For (1, Maxnum/2, (i) = ={Math.pow (i, I+1); Safelist.enqueue (NewBigInteger (i)); }); Parallel.For (Maxnum/2+1, Maxnum, (i) = ={Math.pow (i, I+1); Safelist.enqueue (NewBigInteger (i)); }); }
View Code
Test results:
Test conclusion:
As I expected, the parallel approach would take longer. The impact of thread-safe locking and unlocking on performance is still relatively large.
is the list thread-safe? What if it's not? How much does a safe list affect performance?