如何正确阻止方法直到对象计数器> 0?



你可以认为这个类很奇怪,但它很有教育意义,所以我必须这样做。

class petriPool {
    private int[] nodes = new int[3];
    private int counter;
    private readonly object _lock = new object(); 
    public petriPool (int n, int m) {
        this.nodes[0] = n;
        this.nodes[1] = 0;
        this.nodes[2] = 0;
        this.counter  = m;
    }
    public bool start() {
        lock (_lock) {
            if (this.nodes[0] != 0 && counter != 0) {
                this.nodes[0]--;
                this.nodes[1]++;
                counter--;
                return true;   
            } else
                return false;
    }}
    public bool stop() {
        lock (_lock) {
            if (this.nodes[1] != 0) {
                this.nodes[1]--;
                this.nodes[2]++;
                counter++;
                return true;   
            } else
                return false;
    }}
}

我需要让start()方法等待,直到counter得到值> 0。我可以这么做:

public bool start() {
    while (this.counter == 0) {
        Thread.Sleep(10);
    }
    lock (_lock) {
        if (this.nodes[0] != 0 && counter != 0) {
            this.nodes[0]--;
            this.nodes[1]++;
            counter--;
            return true;   
        } else
            return false;
}}

但没有更好的解决方案吗?我的意思是,看起来我可以少睡一会儿。

看看它需要什么。我在启动线程之前调用start,在线程结束时调用stop。所以计数器必须反映在同一时间内运行的最大线程数。

像这样的信号发送是通过使用事件类来完成的。在您的情况下,ManualResetEventSlim应该足够了。

您可以等待它而不是while循环,并且可以在计数器为零时设置它。

您可以考虑使用"ManualResetEvent"来混合两个线程。

遵循未经测试的代码可能会有所帮助。

class petriPool 
{
    private int[] nodes = new int[3];
    private int counter;
    private ManualResetEvent mevent;
    private readonly object _lock = new object(); 
    public petriPool (int n, int m) 
    {
        mevent= new ManualResetEvent(false);
        this.nodes[0] = n;
        this.nodes[1] = 0;
        this.nodes[2] = 0;
        this.counter  = m;
    }
    public bool start() 
    {
        lock (_lock) 
        {
            if (this.nodes[0] != 0 && counter != 0) 
            {
                this.nodes[0]--;
                this.nodes[1]++;
                counter--;
                if(counter>0) mevent.Set();
                return true;   
            } else
                return false;   
        }
    }
    public bool stop() 
    {
        mevent.WaitOne();
        lock (_lock) {

            if (this.nodes[1] != 0) {
                this.nodes[1]--;
                this.nodes[2]++;
                counter++;
                return true;   
            } else
                return false;
        }
        //reset 'mevent' if you want.
    }
}

最新更新