c# - why does the thread get the demo.names is null? -


here code:

class program {     static void main(string[] args)     {         (int = 0; < 200; i++)         {             console.writeline("---------" + i.tostring());             demo.testerror();         }     }      public class demo     {         public demo() { }          public demo(int i) { index = i; }          public static void testerror()         {             list<thread> threads = new list<thread>();             demo demo = null;             (int = 0; < 1000; i++)             {                 if (i % 10 == 0)                 {                     demo = new demo(i);                 }                 #region code1                 thread t = new thread(() =>                 {                     demo.setname();                     var names = demo.names;                     string msg = null;                     if (names == null)                     {                         msg = demo.index.tostring() + " -" + thread.currentthread.managedthreadid.tostring() + "-is null";                         console.write(msg);                     }                     else if (names == null || names.count <= 0)                     {                         msg = demo.index.tostring() + " -" + thread.currentthread.managedthreadid.tostring() + "-is zero";                         console.write(msg);                     }                     else                     {                         msg = demo.index.tostring() + " -" + thread.currentthread.managedthreadid.tostring() + "-is ok" + "-" + string.join(",", names);                     }                 });                 t.start();                 #endregion                 threads.add(t);             }             (int = 0; < threads.count; i++)             {                 threads[i].join();             }         }          public list<string> names;          public int index;          public object lockobj = new object();          public void setname()         {             if (names == null)             {                 lock (lockobj)                 {                     if (names == null)                     {                         var tnames = new list<string>();                         tnames.add("a");                         system.threading.interlocked.compareexchange(ref names, tnames, null);                     }                 }             }         }     } 

run it, , shows(partial) :

---------60 750 -747-is null---------61 ---------62

...

---------95 960 -5174-is null---------96 ---------97

...

---------101 580 -3591-is null---------102 ---------103

...

---------112 720 -2193-is null---------113 ---------114

...

---------123 50 -2790-is null---------124 ---------125

...

---------133 420 -1237-is null---------134 ---------135

...

change code1 code2:

                #region code2                 thread t = new thread((obj) =>                 {                     var d = obj demo;                     d.setname();                     var names = d.names;                     ...//the same above                 });                 t.start(demo);                 #endregion 

it runs success! what's difference between

public thread(threadstart start); 

and

public thread(parameterizedthreadstart start); 

? , why demo.names null or its'count zero?

they're different in parameterizedthreadstart gets object input threadstart doesn't, simple that.

so why 1 of them works , other doesn't? it's because of variable scope. once use parameterizedthreadstart passes demo variable parameter when for loop iterates next run, doesn't change reference, whereas in first code you're using same object , sharing among threads.

the main problem being you've defined demo variable outside for block.so race condition occurring you're changing reference of variable (demo) briskly in loop, whereas it's still being used in threads.

demo demo = null; (int = 0; < 1000; i++) {   if (i % 10 == 0)   {      demo = new demo(i);   }   ... } 

if change code this, should fixed , work in both scenarios :

for (int = 0; < 1000; i++) {   demo demo = null;   if (i % 10 == 0)   {      demo = new demo(i);   }   ... } 

Comments

Popular posts from this blog

sql - invalid in the select list because it is not contained in either an aggregate function -

Angularjs unit testing - ng-disabled not working when adding text to textarea -

How to start daemon on android by adb -