What will happen in the scenario you describe for C# (not sure about Java but I believe it will behave similar) is that the value i will be stored in short term storage (either the stack or register depending on what the JIT wants to do). This is because it is a value type. If it was a reference type, then it would most likely go on the heap.
Each time the function is called (regardless of thread) the function will get a new instance of the variable i. So it doesn't matter which thread, or how many threads, only how many calls to the function are made.
One thing to note is that you can't always guarantee where something will be allocated, and for the most part you shouldn't care. The JIT/CLR is allowed to do whatever it wants so long as it doesn't affect the single threaded view of the events and the functionality of the program (there are edge cases, but for 99% of code this statement is correct).
You can also read Eric Lippert's answer to this question (Fields of class, are they stored in the stack or heap?) for a better understanding as well as his blog (http://blogs.msdn.com/b/ericlippert/) and (http://ericlippert.com/) he's discussed this a number of times in greater detail.