Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / libs / c5 / UserGuideExamples / Locking.cs @ 3

1
// C5 example: locking 2005-11-07
2

    
3
// Compile with 
4
//   csc /r:C5.dll Locking.cs 
5

    
6
using System;
7
using System.Threading;
8
using C5;
9
using SCG = System.Collections.Generic;
10

    
11
namespace Locking {
12
  class Locking {
13
    static ArrayList<int> coll = new ArrayList<int>();
14
    // static SCG.List<int> coll = new SCG.List<int>();
15
    static readonly int count = 1000;
16

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

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

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

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

    
45
    public static void RunTwoThreads(Act run) {
46
      Thread t1 = new Thread(new ThreadStart(run)),
47
             t2 = new Thread(new ThreadStart(run));
48
      t1.Start(); t2.Start();
49
      t1.Join(); t2.Join();
50
    }
51

    
52
    // Concurrently adding to and removing from an arraylist
53

    
54
    public static void AddAndRemove(int count) {
55
      for (int i=0; i<count; i++) 
56
        coll.Add(i);
57
      for (int i=0; i<count; i++)
58
        coll.Remove(i);
59
    }
60

    
61
    private static readonly Object sync = new Object();
62

    
63
    public static void SafeAddAndRemove(int count) {
64
      for (int i=0; i<count; i++) 
65
        lock (sync)
66
          coll.Add(i);
67
      for (int i=0; i<count; i++)
68
        lock (sync)
69
          coll.Remove(i);
70
    }
71

    
72
    public static void SafeAdd<T>(IExtensible<T> coll, T x) { 
73
      lock (sync) {
74
        coll.Add(x);
75
      }
76
    }
77

    
78
    public static void Move<T>(ICollection<T> from, ICollection<T> to) { 
79
      if (!from.IsEmpty) {  
80
        T x = from.Choose();
81
        Thread.Sleep(0);        // yield processor to other threads
82
        from.Remove(x);
83
        to.Add(x);
84
      }
85
    }
86
    
87
    public static void SafeMove<T>(ICollection<T> from, ICollection<T> to) { 
88
      lock (sync) 
89
        if (!from.IsEmpty) {  
90
          T x = from.Choose();
91
          Thread.Sleep(0);      // yield processor to other threads
92
          from.Remove(x);
93
          to.Add(x);
94
        }
95
    }
96
  }
97
}