Interlocked.Increment Method

定義

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。 Increments a specified variable and stores the result, as an atomic operation.

オーバーロード

Increment(Int32)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。 Increments a specified variable and stores the result, as an atomic operation.

Increment(Int64)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。 Increments a specified variable and stores the result, as an atomic operation.

Increment(Int32)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。 Increments a specified variable and stores the result, as an atomic operation.

public static int Increment (ref int location);
パラメーター
location
Int32

値がインクリメントされる変数。 The variable whose value is to be incremented.

戻り値

インクリメントされた値。 The incremented value.

例外

location のアドレスは null ポインターです。 The address of location is a null pointer.

次の例は、中間値を 1,000 の乱数を生成する 0 から 1,000 までランダムな番号の数が必要ですかを判断します。The following example determines how many random numbers that range from 0 to 1,000 are required to generate 1,000 random numbers with a midpoint value. 中間値、変数の数を追跡するmidpointCountを 0 に設定し、乱数ジェネレーターが 10,000 に達するまで、中間値を返しますたびに増分されます。To keep track of the number of midpoint values, a variable, midpointCount, is set equal to 0 and incremented each time the random number generator returns a midpoint value until it reaches 10,000. 3 つのスレッド、乱数を生成するため、Increment(Int32)メソッドを呼び出して複数のスレッドを更新しないことを確認するmidpointCount同時にします。Because three threads generate the random numbers, the Increment(Int32) method is called to ensure that multiple threads don't update midpointCount concurrently. ロックも使用する乱数ジェネレーター、および保護することに注意してください、CountdownEventオブジェクトを使用することを確認、Mainメソッドは、次の 3 つのスレッドの前に実行を終了しません。Note that a lock is also used to protect the random number generator, and that a CountdownEvent object is used to ensure that the Main method doesn't finish execution before the three threads.

using System;
using System.Threading;

public class Example
{
   const int LOWERBOUND = 0;
   const int UPPERBOUND = 1001;
   
   static Object lockObj = new Object();
   static Random rnd = new Random();
   static CountdownEvent cte;
   
   static int totalCount = 0;
   static int totalMidpoint = 0;
   static int midpointCount = 0;

   public static void Main()
   {
      cte = new CountdownEvent(1);
      // Start three threads. 
      for (int ctr = 0; ctr <= 2; ctr++) {
         cte.AddCount();
         Thread th = new Thread(GenerateNumbers);
         th.Name = "Thread" + ctr.ToString();
         th.Start();
      }
      cte.Signal();
      cte.Wait();
      Console.WriteLine();
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/((double)totalCount));
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount);                  
   }

   private static void GenerateNumbers()
   {
      int midpoint = (UPPERBOUND - LOWERBOUND) / 2;
      int value = 0;
      int total = 0;
      int midpt = 0;
      
      do {
         lock (lockObj) {
            value = rnd.Next(LOWERBOUND, UPPERBOUND);
         }
         if (value == midpoint) { 
            Interlocked.Increment(ref midpointCount);
            midpt++;
         }
         total++;    
      } while (midpointCount < 10000);
      
      Interlocked.Add(ref totalCount, total);
      Interlocked.Add(ref totalMidpoint, midpt);
      
      string s = String.Format("Thread {0}:\n", Thread.CurrentThread.Name) +
                 String.Format("   Random Numbers: {0:N0}\n", total) + 
                 String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, 
                               ((double) midpt)/total);
      Console.WriteLine(s);
      cte.Signal();
   }
}
// The example displays output like the following:
//       Thread Thread2:
//          Random Numbers: 2,776,674
//          Midpoint values: 2,773 (0.100 %)
//       Thread Thread1:
//          Random Numbers: 4,876,100
//          Midpoint values: 4,873 (0.100 %)
//       Thread Thread0:
//          Random Numbers: 2,312,310
//          Midpoint values: 2,354 (0.102 %)
//       
//       Total midpoint values:      10,000 (0.100 %)
//       Total number of values:  9,965,084
Imports System.Threading

Module Example
   Const LOWERBOUND As Integer = 0
   Const UPPERBOUND As Integer = 1001
   
   Dim lockObj As New Object()
   Dim rnd As New Random()
   Dim cte As CountdownEvent
   
   Dim totalCount As Integer = 0
   Dim totalMidpoint As Integer = 0
   Dim midpointCount As Integer = 0

   Public Sub Main()
      cte = New CountdownEvent(1)
      ' Start three threads. 
      For ctr As Integer = 0 To 2
         cte.AddCount()
         Dim th As New Thread(AddressOf GenerateNumbers)
         th.Name = "Thread" + ctr.ToString()
         th.Start()
      Next
      cte.Signal()
      cte.Wait()
      Console.WriteLine()
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/totalCount)
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount)                  
   End Sub
   
   Private Sub GenerateNumbers()
      Dim midpoint As Integer = (upperBound - lowerBound) \ 2
      Dim value As Integer = 0
      Dim total As Integer = 0
      Dim midpt As Integer = 0
      Do
         SyncLock lockObj
            value = rnd.Next(lowerBound, upperBound)
         End SyncLock
         If value = midpoint Then 
            Interlocked.Increment(midpointCount)
            midpt += 1
         End If
         total += 1    
      Loop While midpointCount < 10000
      
      Interlocked.Add(totalCount, total)
      Interlocked.Add(totalMidpoint, midpt)
      
      Dim s As String = String.Format("Thread {0}:", Thread.CurrentThread.Name) + vbCrLf +
                        String.Format("   Random Numbers: {0:N0}", total) + vbCrLf +
                        String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, midpt/total)
      Console.WriteLine(s)
      cte.Signal()
   End Sub
End Module
' The example displays output like the following:
'       Thread Thread2:
'          Random Numbers: 2,776,674
'          Midpoint values: 2,773 (0.100 %)
'       Thread Thread1:
'          Random Numbers: 4,876,100
'          Midpoint values: 4,873 (0.100 %)
'       Thread Thread0:
'          Random Numbers: 2,312,310
'          Midpoint values: 2,354 (0.102 %)
'       
'       Total midpoint values:      10,000 (0.100 %)
'       Total number of values:  9,965,084

使用する点を除いて、次の例は、1 つ前のようなTask50,000 の中間点をランダムな整数を生成するスレッドのプロシージャではなくクラス。The following example is similar to the previous one, except that it uses the Task class instead of a thread procedure to generate 50,000 random midpoint integers. この例では、ラムダ式が置き換えられます、 GenerateNumbers 、スレッド プロシージャを呼び出すまで、Task.WaitAllのメソッドが不要、CountdownEventオブジェクト。In this example, a lambda expression replaces the GenerateNumbers thread procedure, and the call to the Task.WaitAll method eliminates the need for the CountdownEvent object.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   const int LOWERBOUND = 0;
   const int UPPERBOUND = 1001;
   
   static Object lockObj = new Object();
   static Random rnd = new Random();
   
   static int totalCount = 0;
   static int totalMidpoint = 0;
   static int midpointCount = 0;

   public static void Main()
   {
      List<Task> tasks = new List<Task>();
      // Start three tasks. 
      for (int ctr = 0; ctr <= 2; ctr++) 
         tasks.Add(Task.Run( () => { int midpoint = (UPPERBOUND - LOWERBOUND) / 2;
                                     int value = 0;
                                     int total = 0;
                                     int midpt = 0;
                                    
                                     do {
                                        lock (lockObj) {
                                           value = rnd.Next(LOWERBOUND, UPPERBOUND);
                                        }
                                        if (value == midpoint) { 
                                           Interlocked.Increment(ref midpointCount);
                                           midpt++;
                                        }
                                        total++;    
                                     } while (midpointCount < 50000);
                                    
                                     Interlocked.Add(ref totalCount, total);
                                     Interlocked.Add(ref totalMidpoint, midpt);
                                    
                                     string s = String.Format("Task {0}:\n", Task.CurrentId) +
                                                String.Format("   Random Numbers: {0:N0}\n", total) + 
                                                String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, 
                                                              ((double) midpt)/total);
                                     Console.WriteLine(s); } ));
      
      Task.WaitAll(tasks.ToArray());
      Console.WriteLine();
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/((double)totalCount));
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount);                  
   }
}
// The example displays output like the following:
//       Task 3:
//          Random Numbers: 10,855,250
//          Midpoint values: 10,823 (0.100 %)
//       Task 1:
//          Random Numbers: 15,243,703
//          Midpoint values: 15,110 (0.099 %)
//       Task 2:
//          Random Numbers: 24,107,425
//          Midpoint values: 24,067 (0.100 %)
//       
//       Total midpoint values:      50,000 (0.100 %)
//       Total number of values: 50,206,378
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Const LOWERBOUND As Integer = 0
   Const UPPERBOUND As Integer = 1001
   
   Dim lockObj As New Object()
   Dim rnd As New Random()
   
   Dim totalCount As Integer = 0
   Dim totalMidpoint As Integer = 0
   Dim midpointCount As Integer = 0

   Public Sub Main()
      Dim tasks As New List(Of Task)()
      ' Start three tasks. 
      For ctr As Integer = 0 To 2
         tasks.Add(Task.Run( Sub()
                                Dim midpoint As Integer = (upperBound - lowerBound) \ 2
                                Dim value As Integer = 0
                                Dim total As Integer = 0
                                Dim midpt As Integer = 0
                                Do
                                   SyncLock lockObj
                                      value = rnd.Next(lowerBound, upperBound)
                                   End SyncLock
                                   If value = midpoint Then 
                                      Interlocked.Increment(midpointCount)
                                      midpt += 1
                                   End If
                                   total += 1    
                                Loop While midpointCount < 50000
                              
                                Interlocked.Add(totalCount, total)
                                Interlocked.Add(totalMidpoint, midpt)
                              
                                Dim s As String = String.Format("Task {0}:", Task.CurrentId) + vbCrLf +
                                                  String.Format("   Random Numbers: {0:N0}", total) + vbCrLf +
                                                  String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, midpt/total)
                                Console.WriteLine(s)
                             End Sub ))
      Next

      Task.WaitAll(tasks.ToArray())
      Console.WriteLine()
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/totalCount)
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount)                  
   End Sub
End Module
' The example displays output like the following:
'       Task 3:
'          Random Numbers: 10,855,250
'          Midpoint values: 10,823 (0.100 %)
'       Task 1:
'          Random Numbers: 15,243,703
'          Midpoint values: 15,110 (0.099 %)
'       Task 2:
'          Random Numbers: 24,107,425
'          Midpoint values: 24,067 (0.100 %)
'       
'       Total midpoint values:      50,000 (0.100 %)
'       Total number of values: 50,206,378

注釈

このメソッドがラッピングによってオーバーフロー条件を処理します。 場合location = Int32.MaxValuelocation + 1 =Int32.MinValueします。This method handles an overflow condition by wrapping: if location = Int32.MaxValue, location + 1 = Int32.MinValue. 例外をスローすることはありません。No exception is thrown.

Increment(Int64)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。 Increments a specified variable and stores the result, as an atomic operation.

public static long Increment (ref long location);
パラメーター
location
Int64

値がインクリメントされる変数。 The variable whose value is to be incremented.

戻り値

インクリメントされた値。 The incremented value.

例外

location のアドレスは null ポインターです。 The address of location is a null pointer.

注釈

このメソッドがラッピングによってオーバーフロー条件を処理します。 場合location = Int64.MaxValuelocation + 1 =Int64.MinValueします。This method handles an overflow condition by wrapping: if location = Int64.MaxValue, location + 1 = Int64.MinValue. 例外をスローすることはありません。No exception is thrown.

Readメソッドとの 64 ビットのオーバー ロード、 IncrementDecrement、およびAddメソッドは本当に、システムでのみアトミック場所、 System.IntPtr 64 ビット長。The Read method and the 64-bit overloads of the Increment, Decrement, and Add methods are truly atomic only on systems where a System.IntPtr is 64 bits long. 他のシステムでは、これらのメソッドは尊重とデータにアクセスするが、相互にアトミックです。On other systems, these methods are atomic with respect to each other, but not with respect to other means of accessing the data. したがって、32 ビット システムでスレッド セーフにするには、64 ビット値へのアクセスできる必要がありますのメンバーをInterlockedクラス。Thus, to be thread safe on 32-bit systems, any access to a 64-bit value must be made through the members of the Interlocked class.

こちらもご覧ください

適用対象