複数のスレッドが静的メソッドにアクセスする方法を説明できますか?複数のスレッドが静的メソッドに同時にアクセスできますか?静的メソッドとインスタンスメソッド、マルチスレッド、パフォーマンス
私には、メソッドが静的であれば、すべてのスレッドで共有される単一のリソースにすることが論理的であるように見えます。したがって、一度に使用できるスレッドは1つだけです。私はこれをテストするコンソールアプリケーションを作成しました。しかし、私のテストの結果から、私の前提は間違っているように見えます。
私のテストでは、多くのWorker
オブジェクトが構築されています。各Worker
にはいくつかのパスワードとキーがあります。各Worker
には、そのパスワードでパスワードをハッシュするインスタンスメソッドがあります。まったく同じ実装を持つ静的メソッドもありますが、唯一の違いは静的メソッドだけです。 Worker
オブジェクトがすべて作成された後、開始時刻がコンソールに書き込まれます。その後、DoInstanceWork
イベントが発生し、Worker
オブジェクトのすべてがuseInstanceMethod
をスレッドプールにキューイングします。すべてのメソッドまたはすべてのオブジェクトが完了すると、すべてが完了するまでに要した時間が開始時刻から計算され、コンソールに書き込まれます。その後、開始時刻が現在の時刻に設定され、DoStaticWork
イベントが発生します。今回は、すべてWorker
オブジェクトがuseStaticMethod
をスレッドプールにキューイングします。これらのメソッド呼び出しがすべて完了してから完了するまでの時間が再び計算され、コンソールに書き込まれます。
オブジェクトがインスタンスメソッドを使用する時間が、静的メソッドを使用する時間の1/8になると予想していました。私のマシンは4つのコアと8つの仮想スレッドを持っているため1/8です。しかし、そうではありませんでした。実際、静的メソッドを使用するときの時間は実際には分けて速かったです。
これはどのようにですか?フードの下で何が起こっていますか?各スレッドは静的メソッドの独自のコピーを取得しますか?ここで
は、あなたがそれを防ぐために、明示的な仕事をしていない限り、静的またはインスタンス、いずれかのスレッドが任意の時点で任意のメソッドにアクセスできるかどうか、すべての場合において、コンソールAPP-
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading;
namespace bottleneckTest
{
public delegate void workDelegate();
class Program
{
static int num = 1024;
public static DateTime start;
static int complete = 0;
public static event workDelegate DoInstanceWork;
public static event workDelegate DoStaticWork;
static bool flag = false;
static void Main(string[] args)
{
List<Worker> workers = new List<Worker>();
for(int i = 0; i < num; i++){
workers.Add(new Worker(i, num));
}
start = DateTime.UtcNow;
Console.WriteLine(start.ToString());
DoInstanceWork();
Console.ReadLine();
}
public static void Timer()
{
complete++;
if (complete == num)
{
TimeSpan duration = DateTime.UtcNow - Program.start;
Console.WriteLine("Duration: {0}", duration.ToString());
complete = 0;
if (!flag)
{
flag = true;
Program.start = DateTime.UtcNow;
DoStaticWork();
}
}
}
}
public class Worker
{
int _id;
int _num;
KeyedHashAlgorithm hashAlgorithm;
int keyLength;
Random random;
List<byte[]> _passwords;
List<byte[]> _keys;
List<byte[]> hashes;
public Worker(int id, int num)
{
this._id = id;
this._num = num;
hashAlgorithm = KeyedHashAlgorithm.Create("HMACSHA256");
keyLength = hashAlgorithm.Key.Length;
random = new Random();
_passwords = new List<byte[]>();
_keys = new List<byte[]>();
hashes = new List<byte[]>();
for (int i = 0; i < num; i++)
{
byte[] key = new byte[keyLength];
new RNGCryptoServiceProvider().GetBytes(key);
_keys.Add(key);
int passwordLength = random.Next(8, 20);
byte[] password = new byte[passwordLength * 2];
random.NextBytes(password);
_passwords.Add(password);
}
Program.DoInstanceWork += new workDelegate(doInstanceWork);
Program.DoStaticWork += new workDelegate(doStaticWork);
}
public void doInstanceWork()
{
ThreadPool.QueueUserWorkItem(useInstanceMethod, new WorkerArgs() { num = _num, keys = _keys, passwords = _passwords });
}
public void doStaticWork()
{
ThreadPool.QueueUserWorkItem(useStaticMethod, new WorkerArgs() { num = _num, keys = _keys, passwords = _passwords });
}
public void useInstanceMethod(object args)
{
WorkerArgs workerArgs = (WorkerArgs)args;
for (int i = 0; i < workerArgs.num; i++)
{
KeyedHashAlgorithm hashAlgorithm = KeyedHashAlgorithm.Create("HMACSHA256");
hashAlgorithm.Key = workerArgs.keys[i];
byte[] hash = hashAlgorithm.ComputeHash(workerArgs.passwords[i]);
}
Program.Timer();
}
public static void useStaticMethod(object args)
{
WorkerArgs workerArgs = (WorkerArgs)args;
for (int i = 0; i < workerArgs.num; i++)
{
KeyedHashAlgorithm hashAlgorithm = KeyedHashAlgorithm.Create("HMACSHA256");
hashAlgorithm.Key = workerArgs.keys[i];
byte[] hash = hashAlgorithm.ComputeHash(workerArgs.passwords[i]);
}
Program.Timer();
}
public class WorkerArgs
{
public int num;
public List<byte[]> passwords;
public List<byte[]> keys;
}
}
}
コード対データ+1。 –
読み取り専用リソースであるメソッドについての説明をありがとう。私は、私の理解の大きな違いは、同じリソースを同時に多くのスレッドがどのように読むことができるかということです。私はコンピュータの基本的な理解にかなり基本的だと思います。私は無意識のうちに、実際には多くのスレッドで何度も読むことができると思ったときに、メソッドが1クロックサイクルに1回しか読み込めないと思っていました。しかし、すべてが1クロックサイクル内に発生するため、読み込みが並行しているように見えるのは本当ですか?また、メソッドの読み込み方法は?すべて一度に、またはセクションで?ありがとう –