在一个类里写了一个puclib static的方法。
声明了一个互斥体:static Mutex m = new Mutex(false, "myMutex");
然后在一个取随机数的方法中调用:
        public static string getNo()
        {
            m.WaitOne();            string str = "";
            Random r = new Random();
            int i = r.Next(0, 99);
            str = i.ToString();            m.ReleaseMutex();
            return str;
        }
但是仍然存在两个线程取到同一个随即数的问题,请问怎样解决?

解决方案 »

  1.   

    Random constructor use the current time as Random seed.
    If you call getNo() fast enought, Random r could use the same seed.        public static string getNo(Random r)           //<---
            { 
                m.WaitOne();             string str = ""; 
                int i = r.Next(0, 99); 
                str = i.ToString();             m.ReleaseMutex(); 
                return str; 
            }
     
      

  2.   

    这就是线程同步问题 ,线程锁解决
     
    线程执行的公共部分用线程锁,只有当前线程执行完毕才会执行下一线程 Monitor.Enter(this);//当前对象加锁   //公共代码 Monitor.Exit(this);//当前对象解锁
      

  3.   

    public static string getNo() 
            { 
               Monitor.Enter(this);//当前对象加锁             m.WaitOne();             string str = ""; 
                Random r = new Random(); 
                int i = r.Next(0, 99); 
                str = i.ToString();             m.ReleaseMutex(); 
                return str; 
                Monitor.Exit(this);//当前对象解锁 
             } 
      

  4.   

    应把Random r = new Random(); 提到getNo方法体外,或者加上不相同的种子初始化Random, 这不是线程同步引起的问题,而是Random的种子问题,当两个Random实例有一样的种子时,就会生成一系列相同的伪随机数。
      

  5.   

    这个和线程没关系了Random 需要随机种子的;你那样初始化 Random 是不对的,随机种子都是一样的,当然数也都一样了;
    如果一定要这样初始化用下面的方法;确保随机种子不同就可以了;
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;namespace ConsoleApplication1
    {
    class Program
    {

    public static void getNo()
    {
    int seed = BitConverter.ToInt32(Guid.NewGuid().ToByteArray(),2); //用NewGuid中任意4字节生成随机种子;

    Random r = new Random(seed);
    int i = r.Next(0, 99); Console.WriteLine(i); //这样就不会重复了;
      }
    static void Main(string[] args)
    {

    List<Thread> threads = new List<Thread>();
    for(int i=0;i<10;i++)
    {
    Thread thread = new Thread(getNo);
    threads.Add(thread);

    thread.Start();
    }

    foreach(Thread t in threads)
    {
    t.Join();
    }
    }
    }
    }
      

  6.   

    这个和锁没关系,是Random类的特性导致的
    Random在实力化的时候,如果没有给参数(Seed),就自动取Environment.TickCount,而Environment.TickCount本身的精度不够高,所以当程序运行的足够快时,连续两次取到的Environment.TickCount会相同,随机数种子也就相同,那么取到的第一随机数自然也相同
    建议修改为:
            private static Random r = new Random();        public static string getNo()
            {
                lock(r)
                     return r.Next(0, 99).ToString();
            }
      

  7.   

     Random r = new Random(); 
    的种子没有指定,生成的时间间隔太短导致生成结果一样;
    用Random rd = new Random(Guid.NewGuid().GetHashCode());来获取不同的random结果
      

  8.   

    Random 默认使用
    Environment.TickCount 做随机种子;
    所以实例化过快超过一刻度秒的话就都是一样的了;