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.
返回
递减的值。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 类而不是线程过程来生成50000随机中点整数。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. 在此示例中,lambda 表达式取代了 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. 不会引发异常。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.
返回
递减的值。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. 不会引发异常。No exception is thrown.
另请参阅
适用于
Decrement(UInt32)
重要
此 API 不符合 CLS。
以原子操作的形式递减指定变量的值并存储结果。Decrements a specified variable and stores the result, as an atomic operation.
public:
static System::UInt32 Decrement(System::UInt32 % location);
[System.CLSCompliant(false)]
public static uint Decrement (ref uint location);
public static uint Decrement (ref uint location);
[<System.CLSCompliant(false)>]
static member Decrement : uint32 -> uint32
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.
返回
递减的值。The decremented value.
- 属性
例外
location 的地址是一个 null 指针。The address of location is a null pointer.
适用于
Decrement(UInt64)
重要
此 API 不符合 CLS。
以原子操作的形式递减指定变量的值并存储结果。Decrements a specified variable and stores the result, as an atomic operation.
public:
static System::UInt64 Decrement(System::UInt64 % location);
[System.CLSCompliant(false)]
public static ulong Decrement (ref ulong location);
public static ulong Decrement (ref ulong location);
[<System.CLSCompliant(false)>]
static member Decrement : uint64 -> uint64
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.
返回
递减的值。The decremented value.
- 属性
例外
location 的地址是一个 null 指针。The address of location is a null pointer.