Int itemindex itemsindexofitem if itemindex 0 if the

Info icon This preview shows pages 658–661. Sign up to view the full content.

View Full Document Right Arrow Icon
int itemIndex = items.IndexOf(item); if (itemIndex > 0) { items.RemoveAt(itemIndex); } // If the item's already the first, we don't need to do anything. if (itemIndex != 0) { 634 | Chapter 16: Threads and Asynchronous Code
Image of page 658

Info icon This preview has intentionally blurred sections. Sign up to view the full version.

View Full Document Right Arrow Icon
items.Insert(0, item); // Ensure we have no more than the maximum specified // number of items. if (items.Count > maxItems) { items.RemoveAt(items.Count - 1); } } } public IEnumerable<string> GetItems() { return items.ToArray(); } } Example 16-10 is some test code to exercise the class. Example 16-10. Testing the MostRecentlyUsed class const int Iterations = 10000; static void TestMru(MostRecentlyUsed mru) { // Initializing random number generator with thread ID ensures // each thread provides different data. (Although it also makes // each test run different, which may not be ideal.) Random r = new Random(Thread.CurrentThread.ManagedThreadId); string[] items = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight" }; for (int i = 0; i < Iterations; ++i) { mru.UseItem(items[r.Next(items.Length)]); } } Example 16-10 just feeds in strings from a fixed set of items at random. Calling this test function from just one thread produces the expected results: at the end, the Mos tRecentlyUsed object just returns the most recent items put into it by this test. However, the multithreaded test in Example 16-11 causes something quite different to happen. Example 16-11. Executing a multithreaded test MostRecentlyUsed mru = new MostRecentlyUsed(4); const int TestThreadCount = 2; List<Thread> threads = (from i in Enumerable.Range(0, TestThreadCount) select new Thread(() => TestMru(mru))).ToList(); threads.ForEach(t => t.Start()); threads.ForEach(t => t.Join()); foreach (string item in mru.GetItems()) { Synchronization Primitives | 635
Image of page 659
Console.WriteLine(item); } This example crashes on a multicore machine—after awhile, it throws an ArgumentOu tOfRangeException . It doesn’t crash at the same place on every run; it crashes inside either of the two calls to the List<T> class’s RemoveAt method. The exceptions occur due to races. For instance, consider this line of code from Ex- ample 16-9 : items.RemoveAt(items.Count - 1); This reads the value of the Count property, then subtracts 1 to get the index of the last item in the list, and then removes that last item. The race here is that some other thread may manage to remove an item from the list in between this thread reading the Count property and calling RemoveAt . This causes the method to throw an ArgumentOutOfRan geException , because we end up asking it to remove an item at an index that’s after the final item. In fact, we’re lucky we got an exception at all. The List<T> class makes no guarantees when we use it from multiple threads. Here’s what the documentation for the class says in the Thread Safety section: Public static members of this type are thread safe. Any instance members are not guar- anteed to be thread safe. This means that it’s our problem to make sure we never try to use a List<T> instance from more than one thread at a time. It could fail in subtler ways than crashing—it could corrupt data, for example.
Image of page 660

Info icon This preview has intentionally blurred sections. Sign up to view the full version.

View Full Document Right Arrow Icon
Image of page 661
This is the end of the preview. Sign up to access the rest of the document.

{[ snackBarMessage ]}

What students are saying

  • Left Quote Icon

    As a current student on this bumpy collegiate pathway, I stumbled upon Course Hero, where I can find study resources for nearly all my courses, get online help from tutors 24/7, and even share my old projects, papers, and lecture notes with other students.

    Student Picture

    Kiran Temple University Fox School of Business ‘17, Course Hero Intern

  • Left Quote Icon

    I cannot even describe how much Course Hero helped me this summer. It’s truly become something I can always rely on and help me. In the end, I was not only able to survive summer classes, but I was able to thrive thanks to Course Hero.

    Student Picture

    Dana University of Pennsylvania ‘17, Course Hero Intern

  • Left Quote Icon

    The ability to access any university’s resources through Course Hero proved invaluable in my case. I was behind on Tulane coursework and actually used UCLA’s materials to help me move forward and get everything together on time.

    Student Picture

    Jill Tulane University ‘16, Course Hero Intern