Background
The following code snippet is taken from a problem in, Visual C# 2005: How to Program, by Paul and Harvey Deitel (pp. 735). The code snippet is more or less an application for accessing data using 2 threads via a buffer (called shared). Just skip the code snippet, and look below if you would like a brief description of what is going on (before reading my question).
// Fig. 15.8: UnsynchronizedBufferTest.cs
// Showing multiple threads modifying a shared object without
// synchronization.
using System;
using System.Threading;
class UnsynchronizedBufferTest
{
static void Main(string[] args)
{
// create shared object used by threads
UnsynchronizedBufferTest shared = new UnsynchronizedBuffer();
// Random object used by each thread
Random random = new Random();
// create Producer and Consumer objects
Producer producer = new Producer(shared, random);
Consumer consumer = new Consumer(shared, random);
// create threads for producer and consumer and set
// delegates for each thread
Thread producerThread =
new Thread(new ThreadStart(producer.Produce));
producerThread.Name = "Producer";
Thread consumerThread =
new Thread(new ThreadStart(consumer.Consume));
consumerThread.Name = "Consumer";
// start each thread
producerThread.Start();
consumerThread.Start();
} // end Main
} // end class UnsynchronizedBufferTest
Just for the basic idea of what is going on here, a producer thread is running that puts data into a buffer (called shared). Also, a consumer thread is running that gets the data from the buffer.
The Producer and Consumer objects are somehow sharing this buffer, which is what I am having trouble understanding. From what I have always understood about the C# language, when an object is passed to a method, it is only a copy or instance that actually gets passed. I guess that must be wrong, because when the Producer puts the data in the buffer, the Consumer sees it...
The code snippet for the buffer (in case anyone needs that) is as follows (pp. 734). Honestly I don't think it will have anything to do with the answer, and that the answer has more to do with the C# language because really all this class represents is an integer.
// Fig. 15.7: UnsynchronizedBuffer.cs
// An unsynchronized shared buffer implementation.
using System;
using System.Threading;
// this class represents a single shared int
public class UnsynchronizedBuffer : Buffer
{
// buffer shared by producer and consumer threads
private int buffer = -1;
// property buffer
public int Buffer
{
get
{
Console.WriteLine("{0} reads {1}",
Thread.CurrentThread.Name, buffer);
return buffer;
} // end get
set
{
Console.WriteLine("{0} writes {1}",
Thread.CurrentThread.Name, value);
buffer = value;
} // end set
} // end property Buffer
} // end class UnsynchronizedBuffer
Question
How is it that both objects (the Producer and the Consumer) are able to see the changes that each other makes? (i.e. when the Producer sets the data, the Consumer can see the new data)
I must be missing something in my fundamental understanding of C#.