我要实现一个Thread2每循环赛一次.都给Thread1一个脉冲.让其验证一次counter.符合的话会执行下去直到退出..不符合的话就返回Thread2..但我修改了多次都抛出一个"System.Threading.SynchronizationLockException: 从不同步的代码块中调用了对象同步方法。" 的异常..请问是什么问题引起的..有什么解决方法?using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace TreadText
{
    class Program
    {
        private int counter=0;
        static void Main(string[] args)
        {
            Program p = new Program();
            p.DoText();
        }        public void DoText()
        {
            Thread[] myThreads =
            {
                new Thread(new ThreadStart(Decrementer)),
                new Thread(new ThreadStart(Incrementer))
                //new Thread(new ThreadStart(Decrementer)),
                //new Thread(new ThreadStart(Incrementer))
            };
            int ctr=1;
            foreach (Thread myThread in myThreads)
            {
                myThread.IsBackground = true;
                myThread.Name = "Thread" + ctr.ToString();
                ctr++;
                Console.WriteLine("[{0}] is started.",myThread.Name);
                myThread.Start();
                Thread.Sleep(500);
            }
            foreach (Thread myThread in myThreads)
                myThread.Join();
        }        void Decrementer()
        {
            try
            {
                Monitor.Enter(this);
                while(counter<5)
                //if (counter < 10)
                {
                    Console.WriteLine("[{0}] is waiting...counter is {1}", Thread.CurrentThread.Name, counter);
                    Monitor.Wait(this);
                }
                while (counter > 0)
                {
                    int temp = counter;
                    temp--;
                    Thread.Sleep(1);
                    counter = temp;
                    Console.WriteLine("[{0}] in Decrementer.counter :{1}", Thread.CurrentThread.Name, counter);
                }
            }
            finally
            {
                Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
                Monitor.Exit(this);
            }
        }        void Incrementer()
        {
            try
            {
                Monitor.Enter(this);
                while (counter < 10)
                {
                    int temp = counter;
                    temp++;
                    Thread.Sleep(1);
                    counter = temp;
                    Console.WriteLine("[{0}] in Incrementer.counter :{1}", Thread.CurrentThread.Name, counter);
                    Monitor.Pulse(this);
                    Monitor.Exit(this);
                }
                            }
            finally
            {
                Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
                Monitor.Exit(this);
            }
        }
    }
}

解决方案 »

  1.   

    //                    Monitor.Exit(this);
     void Incrementer()
            {
                try
                {
                    Monitor.Enter(this);
                    while (counter < 10)
                    {
                        int temp = counter;
                        temp++;
                        Thread.Sleep(0);
                        counter = temp;
                        Console.WriteLine("[{0}] in Incrementer.counter :{1}", Thread.CurrentThread.Name, counter);
                        Monitor.Pulse(this);
    //                    Monitor.Exit(this);
                    }
                }
                finally
                {
                    Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
                    Monitor.Exit(this);
                }
            }
      

  2.   

          void Incrementer()
            {
                try
                {
                    Monitor.Enter(this);
                    while (counter < 10)
                    {
                        int temp = counter;
                        temp++;
                        Thread.Sleep(1);
                        counter = temp;
                        Console.WriteLine("[{0}] in Incrementer.counter :{1}", Thread.CurrentThread.Name, counter);
                        Monitor.Pulse(this);
                        Monitor.Exit(this); //这一句好像不该有
                    }
                                }
                finally
                {
                    Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
                    Monitor.Exit(this);
                }
      

  3.   

    这句删去的话不能达到我要的效果..他只会把Incrementer()循环完了才回去Decrementer()..不是每循环一次就回去检验一次....
    如果删去下面的一句exit的话问题依然存在..
      

  4.   

    SynchronizationLockException
    线程锁死。
    请检查2个线程是否有访问同一个实例或者对象。
    有的话请将该对象加锁。
    同一对象被2个线程同时访问而没有Lock就会出现该异常。
      

  5.   

    个人感觉可能是2个线程都使用1个COUNT变量造成的- -
    分开声明2个计数变量分别使用试试
      

  6.   

    while(counter<5)
                    //if (counter < 10)
                    {
                        Console.WriteLine("[{0}] is waiting...counter is {1}", Thread.CurrentThread.Name, counter);
                        Monitor.Wait(this);
                    }
                    while (counter > 0)
                    {
                        int temp = counter;
                        temp--;
                        Thread.Sleep(1);
                        counter = temp;
                        Console.WriteLine("[{0}] in Decrementer.counter :{1}", Thread.CurrentThread.Name, counter);
                    }貌似2个While条件也是相互包含的
      

  7.   

          void Decrementer()
            {
                try
                {
                    Monitor.Enter(this);
                    while(counter<5)
                    //if (counter < 10)
                    {
                        Console.WriteLine("[{0}] is waiting...counter is {1}", Thread.CurrentThread.Name, counter);
                        Monitor.Wait(this);   
                        Monitor.Pulse(this);    // 追加
                    }
                    while (counter > 0)
                    {
                        int temp = counter;
                        temp--;
                        Thread.Sleep(1);
                        counter = temp;
                        Console.WriteLine("[{0}] in Decrementer.counter :{1}", Thread.CurrentThread.Name, counter);
                    }
                }
                finally
                {
                    Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
                    Monitor.Exit(this);
                }
            }        void Incrementer()
            {
                try
                {
                    Monitor.Enter(this);
                    while (counter < 10)
                    {
                        int temp = counter;
                        temp++;
                        Thread.Sleep(1);
                        counter = temp;
                        Console.WriteLine("[{0}] in Incrementer.counter :{1}", Thread.CurrentThread.Name, counter);
                        Monitor.Pulse(this);
                        //Monitor.Exit(this);
                        Monitor.Wait(this);   // 更换
                    }
                                }
                finally
                {
                    Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
                    Monitor.Exit(this);
                }
            }应该解决问题了
      

  8.   


    脉冲的问题的确解决了..也没有抛出异常..只是如果这样一来做的话.Decrementer完成以后..Incrementer会一直wait在那里...不往下执行了..用wait(this,1);才能执行下去..
    但问题原因还没搞不懂.........哪位大哥能分析一下为什么会抛出这个异常..
      

  9.   

    1,ncrementer会一直wait在那里   设置timeout 就觉解了问题了啊
    2,对于问题原因  大学没好好学,不胜理解
       谈谈自己的看法而以
       估计 使用Pulse方法释放等待线程的时候,对象有问题,
       调试发现第一次 成功  第二次 出现错误
       我觉得是不是因为两次线程的加锁的对象不同(因为你当中有Exit过)的原因啊引起的啊
      

  10.   

    我大学还没毕业呢............对....我也觉得是应该是EXIT后对象跟之前enter时不同的问题..
    但我尝试用把ENTER放进循环体里面的时候...异常也没有抛出..但就出现了新问题...会循环两次才到回Decrementer()那里..
      

  11.   

    自己再测试一下的时候知道原因了.大概原因是In线程Pulse以后.De线程进入就绪队列里面.这是In线程也EXIT了进入就绪队列....但CPU则先处理IN线程..所以IN就会再执行一次循环..
    只要在IN线程EXIT后SLEEP(1)就可以了.....结贴...!