Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Locking.cs « UserGuideExamples « Mono.C5 « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 303655964077ef3408fc715c4bf88ed16e8bb4d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// C5 example: locking 2005-11-07

// Compile with 
//   csc /r:C5.dll Locking.cs 

using System;
using System.Threading;
using C5;
using SCG = System.Collections.Generic;

namespace Locking {
  class Locking {
    static ArrayList<int> coll = new ArrayList<int>();
    // static SCG.List<int> coll = new SCG.List<int>();
    static readonly int count = 1000;

    public static void Main(String[] args) {
      Console.WriteLine("Adding and removing without locking:");
      RunTwoThreads(delegate { AddAndRemove(15000); });
      Console.WriteLine("coll has {0} items, should be 0", coll.Count);

      coll = new ArrayList<int>();
      Console.WriteLine("Adding and removing with locking:");
      RunTwoThreads(delegate { SafeAddAndRemove(15000); });
      Console.WriteLine("coll has {0} items, should be 0", coll.Count);

      Console.WriteLine("Moving items without locking:");
      ArrayList<int> from, to;
      from = new ArrayList<int>();
      to = new ArrayList<int>();
      for (int i=0; i<count; i++) 
        from.Add(i);
      RunTwoThreads(delegate { while (!from.IsEmpty) Move(from, to); });
      Console.WriteLine("coll has {0} items, should be {1}", to.Count, count);

      Console.WriteLine("Moving items with locking:");
      from = new ArrayList<int>();
      to = new ArrayList<int>();
      for (int i=0; i<count; i++) 
        from.Add(i);
      RunTwoThreads(delegate { while (!from.IsEmpty) SafeMove(from, to); });
      Console.WriteLine("coll has {0} items, should be {1}", to.Count, count);
    }

    public static void RunTwoThreads(Act run) {
      Thread t1 = new Thread(new ThreadStart(run)),
             t2 = new Thread(new ThreadStart(run));
      t1.Start(); t2.Start();
      t1.Join(); t2.Join();
    }

    // Concurrently adding to and removing from an arraylist

    public static void AddAndRemove(int count) {
      for (int i=0; i<count; i++) 
        coll.Add(i);
      for (int i=0; i<count; i++)
        coll.Remove(i);
    }

    private static readonly Object sync = new Object();

    public static void SafeAddAndRemove(int count) {
      for (int i=0; i<count; i++) 
        lock (sync)
          coll.Add(i);
      for (int i=0; i<count; i++)
        lock (sync)
          coll.Remove(i);
    }

    public static void SafeAdd<T>(IExtensible<T> coll, T x) { 
      lock (sync) {
        coll.Add(x);
      }
    }

    public static void Move<T>(ICollection<T> from, ICollection<T> to) { 
      if (!from.IsEmpty) {  
        T x = from.Choose();
        Thread.Sleep(0);        // yield processor to other threads
        from.Remove(x);
        to.Add(x);
      }
    }
    
    public static void SafeMove<T>(ICollection<T> from, ICollection<T> to) { 
      lock (sync) 
        if (!from.IsEmpty) {  
          T x = from.Choose();
          Thread.Sleep(0);      // yield processor to other threads
          from.Remove(x);
          to.Add(x);
        }
    }
  }
}