我正在尝试从两个访问一个资源的线程修复线程同步的问题。在此示例中,该资源是Engine
这里有两个开始启动引擎,其中一个线程正在停止它。 目标是引擎的最终结果
澄清:我不控制ThreadOne / ThreadTwo中的代码,并且需要同步进入Lifecycle
类。
在这个例子中,实现这个目标的最佳方法是什么?
using System;
using System.Threading;
class Program
{
static void Main(string[] args)
{
new Thread(ThreadOne).Start();
new Thread(ThreadTwo).Start();
Console.Read();
}
private static void ThreadOne(object obj)
{
Lifecycle.Start();
Thread.Sleep(500);
Lifecycle.Stop();
}
private static void ThreadTwo(object obj)
{
Thread.Sleep(600);
Lifecycle.Start();
}
}
class Engine
{
public void Start()
{
Console.WriteLine("Engine was started");
}
public void Stop()
{
Console.WriteLine("Engine was stopped");
}
}
static class Lifecycle
{
private static readonly object LockObject;
private static Engine Engine;
static Lifecycle()
{
LockObject = new object();
Engine = new Engine();
}
public static void Start()
{
lock (LockObject)
{
Engine.Start();
Thread.Sleep(800);
}
}
public static void Stop()
{
lock (LockObject)
{
Engine.Stop();
}
}
}
答案 0 :(得分:0)
如果您的目标是多次拨打Start
而不是第二次实际启动
private static bool _isStarted
public static void Start()
{
if(!_isStarted)
{
_isStarted = true;
...
}
}
// set to false in Stop()
这有竞争条件问题。我用简单的变量给出了一个想法。
如果你的目标是打电话给最后一个,那么它就是这样实现的:
static int _counter;
// thread 1
Interlocked.Increment(ref _counter); // instead of start
... // sleep?
Incterlocked.Decrement(ref _counter); // instead of stop
// thread 2
Interlocked.Increment(ref _counter); // instead of start
... // sleep?
// after all threads are finished, check _counter
// positive - means Start()
答案 1 :(得分:0)
Now Lifecycle管理同步
using System;
using System.Threading;
class Program
{
static void Main(string[] args)
{
new Thread(ThreadOne).Start();
new Thread(ThreadTwo).Start();
Console.Read();
}
private static void ThreadOne(object obj)
{
Lifecycle.Start();
Thread.Sleep(500);
Lifecycle.Stop();
}
private static void ThreadTwo(object obj)
{
Thread.Sleep(600);
Lifecycle.Start();
}
}
class Engine
{
public void Start()
{
Console.WriteLine("{0:O} [{1}] Engine was started", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
}
public void Stop()
{
Console.WriteLine("{0:O} [{1}] Engine was stopped", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
}
}
static class Lifecycle
{
private static Engine Engine;
static Lifecycle()
{
Engine = new Engine();
}
public static void Start()
{
Monitor.Enter(Engine);
Engine.Start();
Thread.Sleep(800);
}
public static void Stop()
{
Engine.Stop();
Monitor.Exit(Engine);
}
}
答案 2 :(得分:0)
为什么不直接使用Monitor的方法替换lock
?
internal static class Lifecycle
{
private static Engine Engine;
static Lifecycle()
{
Engine = new Engine();
}
public static void Start()
{
Monitor.Enter(Engine);
Engine.Start();
Thread.Sleep(800);
}
public static void Stop()
{
Engine.Stop();
Monitor.Exit(Engine);
}
}