Interlocked.Decrement 메서드

정의

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements a specified variable and stores the result, as an atomic operation.

오버로드

Decrement(Int32)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements a specified variable and stores the result, as an atomic operation.

Decrement(Int64)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements the specified variable and stores the result, as an atomic operation.

Decrement(UInt32)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements a specified variable and stores the result, as an atomic operation.

Decrement(UInt64)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements a specified variable and stores the result, as an atomic operation.

Decrement(Int32)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements a specified variable and stores the result, as an atomic operation.

public:
 static int Decrement(int % location);
public static int Decrement (ref int location);
static member Decrement : int -> int
Public Shared Function Decrement (ByRef location As Integer) As Integer

매개 변수

location
Int32

값을 감소시킬 변수입니다.The variable whose value is to be decremented.

반환

Int32

감소한 값입니다.The decremented value.

예외

location의 주소는 null 포인터입니다.The address of location is a null pointer.

location의 주소는 null 포인터입니다.The address of location is a null pointer.

예제

다음 예에서는 중간값을 사용 하 여 1000 난수를 생성 하는 데 필요한 0에서 1000 사이의 난수 수를 결정 합니다.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 1000와 동일 하 게 설정 되 고 난수 생성기가 중간값을 반환할 때마다 감소 합니다.To keep track of the number of midpoint values, a variable, midpointCount, is set equal to 1,000 and decremented each time the random number generator returns a midpoint value. 세 개의 스레드가 난수를 생성 하기 때문에 Decrement(Int32) 메서드를 호출 하 여 여러 스레드가 동시에 업데이트 되지 않도록 midpointCount 합니다.Because three threads generate the random numbers, the Decrement(Int32) method is called to ensure that multiple threads don't update midpointCount concurrently. 잠금은 난수 생성기를 보호 하는 데에도 사용 되며, 개체를 사용 하 여 CountdownEvent Main 세 스레드 전에 메서드가 실행을 완료 하지 않도록 합니다.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 = 10000;

   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.Decrement(ref midpointCount);
            midpt++;
         }
         total++;    
      } while (Volatile.Read(ref midpointCount) > 0);
      
      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: 3,204,021
//          Midpoint values: 3,156 (0.099 %)
//       Thread Thread0:
//          Random Numbers: 4,073,592
//          Midpoint values: 4,015 (0.099 %)
//       Thread Thread1:
//          Random Numbers: 2,828,192
//          Midpoint values: 2,829 (0.100 %)
//       
//       Total midpoint values:      10,000 (0.099 %)
//       Total number of values: 10,105,805
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 = 10000

   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.Decrement(midpointCount)
            midpt += 1
         End If
         total += 1    
      Loop While midpointCount > 0
      
      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: 3,204,021
'          Midpoint values: 3,156 (0.099 %)
'       Thread Thread0:
'          Random Numbers: 4,073,592
'          Midpoint values: 4,015 (0.099 %)
'       Thread Thread1:
'          Random Numbers: 2,828,192
'          Midpoint values: 2,829 (0.100 %)
'       
'       Total midpoint values:      10,000 (0.099 %)
'       Total number of values: 10,105,805

다음 예제는 Task 스레드 프로시저 대신 클래스를 사용 하 여 5만 임의 중간점 정수를 생성 한다는 점을 제외 하 고 이전 예제와 비슷합니다.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 = 50000;

   public static async Task 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.Decrement(ref midpointCount);
                                           midpt++;
                                        }
                                        total++;    
                                     } while (Volatile.Read(ref midpointCount) > 0);
                                          
                                     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); 
                                   } ));

      await Task.WhenAll(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 1:
//          Random Numbers: 24,530,624
//          Midpoint values: 24,675 (0.101 %)
//       Task 2:
//          Random Numbers: 7,079,718
//          Midpoint values: 7,093 (0.100 %)
//       Task 3:
//          Random Numbers: 18,284,617
//          Midpoint values: 18,232 (0.100 %)
//       
//       Total midpoint values:      50,000 (0.100 %)
//       Total number of values: 49,894,959
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 = 50000

   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.Decrement(midpointCount)
                                      midpt += 1
                                   End If
                                   total += 1    
                                Loop While midpointCount > 0
                              
                                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 1:
'          Random Numbers: 24,530,624
'          Midpoint values: 24,675 (0.101 %)
'       Task 2:
'          Random Numbers: 7,079,718
'          Midpoint values: 7,093 (0.100 %)
'       Task 3:
'          Random Numbers: 18,284,617
'          Midpoint values: 18,232 (0.100 %)
'       
'       Total midpoint values:      50,000 (0.100 %)
'       Total number of values: 49,894,959

설명

이 메서드는 (If location = Int32.MinValue , location -1 =)를 래핑하여 오버플로 조건을 처리 Int32.MaxValue 합니다.This method handles an overflow condition by wrapping: If location = Int32.MinValue, location - 1 = Int32.MaxValue. 예외는 throw되지 않습니다.No exception is thrown.

추가 정보

적용 대상

Decrement(Int64)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements the specified variable and stores the result, as an atomic operation.

public:
 static long Decrement(long % location);
public static long Decrement (ref long location);
static member Decrement : int64 -> int64
Public Shared Function Decrement (ByRef location As Long) As Long

매개 변수

location
Int64

값을 감소시킬 변수입니다.The variable whose value is to be decremented.

반환

Int64

감소한 값입니다.The decremented value.

예외

location의 주소는 null 포인터입니다.The address of location is a null pointer.

location의 주소는 null 포인터입니다.The address of location is a null pointer.

설명

이 메서드는 (if location = Int64.MinValue , location -1 =)를 래핑하여 오버플로 조건을 처리 Int64.MaxValue 합니다.This method handles an overflow condition by wrapping: if location = Int64.MinValue, location - 1 = Int64.MaxValue. 예외는 throw되지 않습니다.No exception is thrown.

추가 정보

적용 대상

Decrement(UInt32)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements a specified variable and stores the result, as an atomic operation.

public:
 static System::UInt32 Decrement(System::UInt32 % location);
public static uint Decrement (ref uint location);
static member Decrement : uint32 -> uint32
Public Shared Function Decrement (ByRef location As UInteger) As UInteger

매개 변수

location
UInt32

값을 감소시킬 변수입니다.The variable whose value is to be decremented.

반환

UInt32

감소한 값입니다.The decremented value.

예외

location의 주소는 null 포인터입니다.The address of location is a null pointer.

적용 대상

Decrement(UInt64)

원자 단위 연산으로 지정된 변수를 감소시키고 결과를 저장합니다.Decrements a specified variable and stores the result, as an atomic operation.

public:
 static System::UInt64 Decrement(System::UInt64 % location);
public static ulong Decrement (ref ulong location);
static member Decrement : uint64 -> uint64
Public Shared Function Decrement (ByRef location As ULong) As ULong

매개 변수

location
UInt64

값을 감소시킬 변수입니다.The variable whose value is to be decremented.

반환

UInt64

감소한 값입니다.The decremented value.

예외

location의 주소는 null 포인터입니다.The address of location is a null pointer.

적용 대상