Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
System.Threading.SpinLock adalah kunci pengecualian mutual level rendah yang dapat Anda gunakan untuk skenario dengan waktu tunggu sangat singkat.
SpinLock tidak berlarut-larut kembali. Setelah sebuah utas memasuki pengunci, utas tersebut harus keluar dari pengunci dengan benar sebelum dapat masuk lagi. Biasanya, setiap upaya untuk memasukkan kembali kunci akan menyebabkan kebuntuan, dan kebuntuan bisa sangat sulit untuk di-debug. Sebagai bantuan untuk pengembangan, System.Threading.SpinLock mendukung mode pelacakan utas yang menyebabkan pengecualian dilemparkan ketika utas mencoba memasukkan kembali kunci yang sudah dipegangnya. Ini memungkinkan Anda lebih mudah menemukan titik di mana kunci tidak keluar dengan benar. Anda dapat mengaktifkan mode pelacakan thread dengan menggunakan konstruktor SpinLock yang mengambil parameter input Boolean, dengan meneruskan argumen true. Setelah Anda menyelesaikan fase pengembangan dan pengujian, matikan mode pelacakan utas untuk performa yang lebih baik.
Contoh
Contoh berikut menunjukkan mode pelacakan utas. Baris yang keluar dari kunci dengan benar dikomentari untuk mensimulasikan kesalahan pengkodian yang menyebabkan salah satu hasil berikut:
Pengecualian dilemparkan jika SpinLock dibuat dengan menggunakan argumen
true(Truedi Visual Basic).Kebuntuan terjadi jika SpinLock dibuat dengan menggunakan argumen
false(Falsedalam Visual Basic).
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SpinLockDemo
{
// C#
public class SpinLockTest
{
// Specify true to enable thread tracking. This will cause
// exception to be thrown when the first thread attempts to reenter the lock.
// Specify false to cause deadlock due to coding error below.
private static SpinLock _spinLock = new SpinLock(true);
static void Main()
{
Parallel.Invoke(
() => DoWork(),
() => DoWork(),
() => DoWork(),
() => DoWork()
);
Console.WriteLine("Press any key.");
Console.ReadKey();
}
public static void DoWork()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
bool lockTaken = false;
try
{
_spinLock.Enter(ref lockTaken);
// do work here protected by the lock
Thread.SpinWait(50000);
sb.Append(Thread.CurrentThread.ManagedThreadId);
sb.Append(" Entered-");
}
catch (LockRecursionException ex)
{
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} attempted to reenter the lock");
throw;
}
finally
{
// INTENTIONAL CODING ERROR TO DEMONSTRATE THREAD TRACKING!
// UNCOMMENT THE LINES FOR CORRECT SPINLOCK BEHAVIOR
// Commenting out these lines causes the same thread
// to attempt to reenter the lock. If the SpinLock was
// created with thread tracking enabled, the exception
// is thrown. Otherwise the spinlock deadlocks.
if (lockTaken)
{
// _spinLock.Exit(false);
// sb.Append("Exited ");
}
}
// Output for diagnostic display.
if(i % 4 != 0)
Console.Write(sb.ToString());
else
Console.WriteLine(sb.ToString());
sb.Clear();
}
}
}
}
Imports System.Text
Imports System.Threading
Imports System.Threading.Tasks
Module Module1
Public Class SpinTest
' True means "enable thread tracking." This will cause an
' exception to be thrown when the first thread attempts to reenter the lock.
' Specify False to cause deadlock due to coding error below.
Private Shared _spinLock = New SpinLock(True)
Public Shared Sub Main()
Parallel.Invoke(
Sub() DoWork(),
Sub() DoWork(),
Sub() DoWork(),
Sub() DoWork()
)
Console.WriteLine("Press any key.")
Console.ReadKey()
End Sub
Public Shared Sub DoWork()
Dim sb = New StringBuilder()
For i As Integer = 1 To 9999
Dim lockTaken As Boolean = False
Try
_spinLock.Enter(lockTaken)
' do work here protected by the lock
Thread.SpinWait(50000)
sb.Append(Thread.CurrentThread.ManagedThreadId)
sb.Append(" Entered-")
Catch ex As LockRecursionException
Console.WriteLine("Thread {0} attempted to reenter the lock",
Thread.CurrentThread.ManagedThreadId)
Throw
Finally
' INTENTIONAL CODING ERROR TO DEMONSTRATE THREAD TRACKING!
' UNCOMMENT THE LINES FOR CORRECT SPINLOCK BEHAVIOR
' Commenting out these lines causes the same thread
' to attempt to reenter the lock. If the SpinLock was
' created with thread tracking enabled, the exception
' is thrown. Otherwise, if the SpinLock was created with a
' parameter of false, and these lines are left commented, the spinlock deadlocks.
If (lockTaken) Then
' _spinLock.Exit()
' sb.Append("Exited ")
End If
End Try
' Output for diagnostic display.
If (i Mod 4 <> 0) Then
Console.Write(sb.ToString())
Else
Console.WriteLine(sb.ToString())
End If
sb.Clear()
Next
End Sub
End Class
End Module