- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Cigarette Smoker Problem 工作.
我只应该使用 Monitor 类。没有信号/信号量。 (是的,这是给学校的,但不是家庭作业,只是我的实践测试的免费练习,我真的需要做好准备,所以让这个程序工作对我有很大帮助)。
我的问题是我不知道要“锁定”哪些对象等(如您所见,我已经尝试了很多这个,只是随机对象)
我有 4 个线程,1 个经销商,3 个吸烟者。我有一个 Dealer 类和一个 Smoker 类。目前,我所有的 Smokers 都去 Monitor.Wait() 并有 1 或 2 种成分,然后他们再也不会离开它,即使每次经销商将成分放在 table 上时我都会调用 Monitor.PulseAll()。我认为这是因为我使用了错误的对象作为参数而且我完全不知道。
文本框和字符串主要用于在我的 WPF 类中提供数据。
吸烟类:请原谅德语变量名称。 (tabak = 烟草,papier = 纸,streichhölzer = firethingies,zutat = 成分,rauchzeit = smoketime)
class Raucher
{
enum Zutaten { Tabak, Papier, Streichhölzer, Leer };
public static Random r = new Random();
int id;
String status = "";
public static int rauchzeit, rauchzeitvar, drehzeit, drehzeitvar;
TextBox txtbox;
Zutaten zutat1;
Zutaten zutat2;
Zutaten zutat3;
public static Dealer dealer;
public Raucher(Int32 id, Int32 rauchzeit, Int32 rauchzeitvar, Int32 drehzeit, Int32 drehzeitvar, TextBox status1, TextBox status2, TextBox status3, Dealer dealer)
{
this.id = id;
Raucher.rauchzeit = rauchzeit;
Raucher.rauchzeitvar = rauchzeitvar;
Raucher.drehzeit = drehzeit;
Raucher.drehzeitvar = drehzeitvar;
Raucher.dealer = dealer;
status = "Warten";
switch (id)
{
case (0):
txtbox = status1;
zutat1 = Zutaten.Tabak;
break;
case (1):
txtbox = status2;
zutat1 = Zutaten.Papier;
break;
case (2):
txtbox = status3;
zutat1 = Zutaten.Streichhölzer;
break;
}
zutat2 = Zutaten.Leer;
zutat3 = Zutaten.Leer;
}
public void updateText()
{
try
{
txtbox.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal
, new System.Windows.Threading.DispatcherOperationCallback(delegate
{
txtbox.Text = status;
switch (status)
{
case "Drehen":
txtbox.Background = Brushes.White;
break;
case "Rauchen":
txtbox.Background = Brushes.Green;
break;
case "Warten":
txtbox.Background = Brushes.Red;
break;
}
txtbox.UpdateLayout();
return null;
}), null);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
public static readonly object _locker = new object();
public void Go()
{
while (true)
{
lock (_locker)
{
Console.WriteLine("Tabak: " + dealer.tabak);
Console.WriteLine("Papier: " + dealer.papier);
Console.WriteLine("Streichhölzer: " + dealer.streichhölzer);
if (!dealer.tabak && !dealer.papier && !dealer.streichhölzer)
{
Monitor.PulseAll(_locker);
}
if (zutat1 == Zutaten.Tabak)
{
if (dealer.papier && zutat2 == Zutaten.Leer)
{
dealer.takePapier();
zutat2 = Zutaten.Papier;
}
if (dealer.streichhölzer && zutat3 == Zutaten.Leer)
{
dealer.takeStreichhölzer();
zutat3 = Zutaten.Streichhölzer;
}
if (zutat2 == Zutaten.Papier && zutat3 == Zutaten.Streichhölzer)
{
status = "Drehen";
updateText();
Thread.Sleep(r.Next(drehzeit - drehzeitvar, drehzeit + drehzeitvar));
status = "Rauchen";
updateText();
Thread.Sleep(r.Next(rauchzeit - rauchzeitvar, rauchzeit + rauchzeitvar));
zutat2 = Zutaten.Leer;
zutat3 = Zutaten.Leer;
}
else
{
Monitor.Wait(_locker);
}
}
if (zutat1 == Zutaten.Papier)
{
if (dealer.tabak && zutat2 == Zutaten.Leer)
{
dealer.takeTabak();
zutat2 = Zutaten.Tabak;
}
if (dealer.streichhölzer && zutat3 == Zutaten.Leer)
{
dealer.takeStreichhölzer();
zutat3 = Zutaten.Streichhölzer;
}
if (zutat2 == Zutaten.Tabak && zutat3 == Zutaten.Streichhölzer)
{
status = "Drehen";
updateText();
Thread.Sleep(r.Next(drehzeit - drehzeitvar, drehzeit + drehzeitvar));
status = "Rauchen";
updateText();
Thread.Sleep(r.Next(rauchzeit - rauchzeitvar, rauchzeit + rauchzeitvar));
zutat2 = Zutaten.Leer;
zutat3 = Zutaten.Leer;
}
else
{
Monitor.Wait(_locker);
}
}
if (zutat1 == Zutaten.Streichhölzer)
{
if (dealer.papier && zutat2 == Zutaten.Leer)
{
dealer.takePapier();
zutat2 = Zutaten.Papier;
}
if (dealer.tabak && zutat3 == Zutaten.Leer)
{
dealer.takeTabak();
zutat3 = Zutaten.Tabak;
}
if (zutat2 == Zutaten.Papier && zutat3 == Zutaten.Tabak)
{
status = "Drehen";
updateText();
Thread.Sleep(r.Next(drehzeit - drehzeitvar, drehzeit + drehzeitvar));
status = "Rauchen";
updateText();
Thread.Sleep(r.Next(rauchzeit - rauchzeitvar, rauchzeit + rauchzeitvar));
zutat2 = Zutaten.Leer;
zutat3 = Zutaten.Leer;
}
else
{
Monitor.Wait(_locker);
}
}
}
}
}
}
经销商类:
class Dealer
{
public static Random r = new Random();
public Boolean tabak = false;
public Boolean papier = false;
public Boolean streichhölzer = false;
public String zutaten;
public Boolean isEmpty()
{
return !(tabak || papier || streichhölzer);
}
public void setTabak()
{
tabak = true;
}
public void setPapier()
{
papier = true;
}
public void setStreichhölzer()
{
streichhölzer = true;
}
public void takeTabak()
{
tabak = false;
}
public void takePapier()
{
papier = false;
}
public void takeStreichhölzer()
{
streichhölzer = false;
}
TextBox status;
public Dealer(TextBox status)
{
this.status = status;
}
public static readonly object _locker = new object();
public void Go()
{
while (true)
{
if (isEmpty())
{
lock (this)
{
if (!tabak && !papier && !streichhölzer)
{
int zahl1 = r.Next(0, 3);
int zahl2 = r.Next(0, 3);
while (zahl1 == zahl2)
{
zahl2 = r.Next(0, 3);
}
switch (zahl1)
{
case (0):
setTabak();
break;
case (1):
setPapier();
break;
case (2):
setStreichhölzer();
break;
}
switch (zahl2)
{
case (0):
setTabak();
break;
case (1):
setPapier();
break;
case (2):
setStreichhölzer();
break;
}
updateText();
Monitor.PulseAll(this);
}
}
}
}
}
public void updateText()
{
try
{
status.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal
, new System.Windows.Threading.DispatcherOperationCallback(delegate
{
zutaten = "";
if (tabak)
{
zutaten += " Tabak ";
}
if (papier)
{
zutaten += " Papier ";
}
if (streichhölzer)
{
zutaten += " Streichhölzer ";
}
status.Text = zutaten;
status.UpdateLayout();
return null;
}), null);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
最佳答案
有几处错误:
Smoker 和 Dealer 类都有自己的 _locker 对象。如果 Smoker 和 Dealer 线程不以某种方式访问相同的同步原语,它们之间就不会发生同步。
在 Dealer 中,您锁定“this”,并对其进行脉冲。这是没有意义的,因为没有其他线程会知道它,因为只有一个线程(经销商)使用它。
锁定“this”或公共(public)属性/字段是不好的做法。在较大的软件项目中,这种做法很容易导致死锁情况。
不要让每个类都使用彼此的同步对象。只需要让Dealer有一个同步对象,Smokers用它来同步对Dealer资源的访问。但实际上让多个类乱用同步对象也是一种非常糟糕的做法。
更好的方法是在 Dealer 类中拥有一个私有(private)同步对象,并且您以这种方式实现您的应用程序逻辑,以便仅在 Dealer 类内部处理同步,对任何 Smoker 完全透明。
关于c# - 具有监视器进入/退出、等待/脉冲、锁定的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19480335/
如果之前已经回答过这个问题,我深表歉意,但我无法找到我想要的东西。 我有一个 Box2D 动态主体,我对其应用线性脉冲以将其变成射弹。因此,当我单击屏幕上的任意位置时,我希望 body 投影到触摸位置
脉冲神经网络和循环神经网络都可以对时变信息进行建模。但我不确定哪种模型相对于计算成本更好。使用更复杂的脉冲神经网络是否值得,或者循环神经网络是否可以在所需计算量少得多的情况下工作?脉冲网络收敛得更快吗
如何在我的应用程序运行且屏幕打开时使 LED 或轨迹球闪烁或闪烁?比如接到电话时? 谢谢 最佳答案 Android 具有仅在屏幕关闭时 LED 才会亮起的硬编码功能。这是在源代码 Notificati
我的目标是从健身手环获取数据(脉搏)Torntisc T1使用我的应用程序并独立处理来自手环的数据。 为了实现,我使用了 Xamarin 并找到了一个 Bluetooth LE plugin for
我很难理解 Wait()、Pulse()、PulseAll()。他们都能避免僵局吗?如果您解释一下如何使用它们,我将不胜感激? 最佳答案 简短版: lock(obj) {...} 是 Monitor.
我在 Cigarette Smoker Problem 工作. 我只应该使用 Monitor 类。没有信号/信号量。 (是的,这是给学校的,但不是家庭作业,只是我的实践测试的免费练习,我真的需要做好准
我想使用 bcm2835.h 和纯 C 语言通过 PWM 控制 LED 二极管。我的代码不起作用。我错过了什么? 我尝试过“gpio”控制台命令,它工作正常,所以我知道 LED 已连接到正确的端口。我
在 ARKit/SceneKit 中,当用户点击按钮时,我想对我的节点施加一个脉冲。我希望冲动来自当前用户的角度。这意味着节点将远离用户的视角。多亏了这段代码,我能够获得当前的方向/方向: func
我正试图在 SK/SWIFT 中“脉冲”一个 Sprite 。我尝试使用 For 循环和 .setScale 进行粗略尝试,但它们不起作用(没有错误 - 只是没有动画)。我觉得使用 SKActions
我想为以下绘图符号设置动画(脉冲、发光)。实现所需行为的最佳方法是什么。谢谢 最佳答案 您不能为绘图符号设置动画。您可以做的是在突出显示的点上放置一个绘图空间注释。创建一个自定义的 CPTLayer
在 Perl 下,在 Linux 上将 Serial::Device 作为文件打开会重置我的 Arduino,但我不希望它被重置。 Arduino 可以通过脉冲 DTR 来重置,因此默认打开串口设备必
我用 alsa 成功渲染了音频,但是我完全无法确定 channel 映射。正如各种消息来源所说,我调用 snd_pcm_get_chmap设置好硬件和软件参数并准备好设备后。 snd_config_g
我是一名优秀的程序员,十分优秀!