How can I run some threads at the same time without "running twice" or "failing" one of them? I will explain my question with an example:
private int count = 0;
private HashSet<int> hs_pages = new HashSet<int>();
for (int page = 1; page <= 10; page++)
{
Thread thread = new Thread(unused => my_method(page));
thread.Name = "Thread - " + page.ToString();
thread.Start();
}
while(count < 10)
{
}
and my_method()
is implemented as:
public void my_method(int page)
{
if (hs_pages.Add(page))
{
count++;
//My Codes
}
else
{
MessageBox.Show("this is duplicate of page : " + page.ToString());
}
}
after running this code I figured out some pages (1-10) don't run and some pages run twice.
so the while()
never ends because of those duplicates and fails.
How can I fix those duplicates and failures?
My meaning of fail is not "Error", I mean for example my_method(4)
never runs and my meaning of duplicate is for example my_method(3)
runs twice.
I know there are other ways such as Parallel.ForEach
, but I want to learn how to use the Thread Class.
Within a process or program, we can run multiple threads concurrently to improve the performance. Threads, unlike heavyweight process, are lightweight and run inside a single process – they share the same address space, the resources allocated and the environment of that process.
Yes, A program can run two threads at the same time. it is called Multi threading. would they both be able to run at the same time or would my second function wait until the system call finishes?
Because Java threads run in the same memory space, they can easily communicate among themselves because an object in one thread can call a method in another thread without any overhead from the operating system. In this Tutorial we will learn how to do multi-threaded programming in Java.
You're closing over the loop variable.
Closures close over variables not over values. The lambda that you are creating isn't taking a copy of the current value of page
within the body of the loop, it's creating a reference to that variable and it will access that variable's value when the anonymous method is actually executed at some point in the future. By the time that execution actually happens the loop has already continued on and incremented the value some number of times (we won't know how many; it'll depend on how the threads are scheduled).
Make a copy of page
that's local to the body of the loop so that each closure is over a different variable, rather than a single variable that is being mutated:
for (int page = 1; page <= 10; page++)
{
int pageCopy = page;
Thread thread = new Thread(unused => my_method(pageCopy , count));
thread.Name = "Thread - " + pageCopy.ToString();
thread.Start();
}
Also, you shouldn't be doing a busy wait to wait for all of the threads to finish; that's extraordinarily wasteful of system resources to spend lots of CPU time spinning around in the while loop doing nothing. Instead put all of the Thread
object that you create into a List<Thread>
when you create them and then loop through the list again when you're done and call Join
on them all to wait for them to finish.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With