Why not have your parameters be part of the class, make them properties, and have the get/set methods lock around them? If you have enough parameters, make the parameter object itself a property of the object, and then lock that parameter block. As in:
class GonnaDoSomeThreading {
private Object mBlockLock = new Object();
private MyParameterBlock mBlock;
public MyParameterBlock Block {
get {
MyParameterBlock tmp;
lock (mBlockLock){
tmp = new MyParameterBlock(mBlock); //or some other cloning
}
return tmp; //use a tmp in order to make sure that modifications done
//do not modify the block directly, but that modifications must
//be 'committed' through the set function
}
set { lock (mBlockLock){ mBlock = value; } }
}
}
And then do your thread pool as already suggested. That way, you've got locks around the data access, so that if all of your threads need it, they can wait on one another.
If you're doing this for something like image processing (where a lot of parallel objects can be done at once), then it might be better to break up your data into individualized chunks. IE, say you want to run some convolution over a largish image, and so want to break it up into two halves. Then, you can have a 'Fragmentimage' function which creates the image blocks that you're going to work on individually, and then a 'MergeFragments' function call to join all the results. So your fragment could look like:
class ThreadWorkFragment {
<image type, like ushort>[] mDataArray;
bool mDone;
}
Put a lock around that fragment (ie, a list of objects and fragments, with each having a lock and so forth), so that when the thread accesses it's fragment, it can eventually state that it's 'done', release the lock, and then you can have a final merge function which just waits for those done booleans to be flagged. That way, if one of the threads dies before setting done, and you know the thread's dead, then you also know that the thread didn't finish its work and you need to do some error recovery; if you just wait for a join to happen, the thread could still have messed up its fragment.
But there's a lot of those kinds of specific ideas to implement, based on the problem you're trying to solve.