Генератор случайных чисел, генерирующий только одно случайное число

long d1Ms=asa.getTime();   
long d2Ms=asa2.getTime();   
long minute = Math.abs((d1Ms-d2Ms)/60000);   
int Hours = (int)minute/60;     
int Minutes = (int)minute%60;     
stUr.setText(Hours+":"+Minutes); 
725
задан Taryn 22 March 2017 в 16:19
поделиться

5 ответов

Каждый раз, когда вы делаете new Random () , он инициализируется с использованием часов. Это означает, что в тесном цикле вы получаете одно и то же значение много раз. Вы должны сохранить один Случайный экземпляр и продолжать использовать Далее на том же том же экземпляре .

//Function to get a random number 
private static readonly Random random = new Random(); 
private static readonly object syncLock = new object(); 
public static int RandomNumber(int min, int max)
{
    lock(syncLock) { // synchronize
        return random.Next(min, max);
    }
}

Редактировать (см. Комментарии): зачем нам нужен lock здесь?

По сути, Далее собирается изменить внутреннее состояние Случайного экземпляра. Если мы сделаем это одновременно из нескольких потоков, вы могли бы утверждать, что «мы только что сделали результат еще более случайным», но то, что мы на самом деле делаем , потенциально нарушает внутренняя реализация, и мы могли бы также начать получать одни и те же числа из разных потоков, что может быть проблемой - и не может. Гарантия того, что происходит внутри, является более важной проблемой; поскольку Случайное не не не дает никаких гарантий безопасности потоков. Таким образом, существует два допустимых подхода:

  • синхронизировать, чтобы мы не обращались к нему одновременно из разных потоков
  • использовать разные случайные экземпляры на поток

Любой из них может быть в порядке; но мьютекс одного единственного экземпляра от нескольких вызывающих абонентов в одно и то же время просто вызывает проблемы.

Блокировка обеспечивает первый (и более простой) из этих подходов; однако, другой подход может быть следующим:

private static readonly ThreadLocal<Random> appRandom
     = new ThreadLocal<Random>(() => new Random());

это тогда для каждого потока, поэтому вам не нужно синхронизировать.

поскольку Случайное не не не дает никаких гарантий безопасности потоков. Таким образом, существует два допустимых подхода:

  • синхронизировать, чтобы мы не обращались к нему одновременно из разных потоков
  • использовать разные случайные экземпляры на поток

Любой из них может быть в порядке; но мьютекс одного единственного экземпляра от нескольких вызывающих абонентов в одно и то же время просто вызывает проблемы.

Блокировка обеспечивает первый (и более простой) из этих подходов; однако, другой подход может быть следующим:

private static readonly ThreadLocal<Random> appRandom
     = new ThreadLocal<Random>(() => new Random());

это тогда для каждого потока, поэтому вам не нужно синхронизировать.

поскольку Случайное не не не дает никаких гарантий безопасности потоков. Таким образом, существует два допустимых подхода:

  • синхронизировать, чтобы мы не обращались к нему одновременно из разных потоков
  • использовать разные случайные экземпляры на поток

Любой из них может быть в порядке; но мьютекс одного единственного экземпляра от нескольких вызывающих абонентов в одно и то же время просто вызывает проблемы.

Блокировка обеспечивает первый (и более простой) из этих подходов; однако, другой подход может быть следующим:

private static readonly ThreadLocal<Random> appRandom
     = new ThreadLocal<Random>(() => new Random());

это тогда для каждого потока, поэтому вам не нужно синхронизировать.

t получить к нему доступ одновременно из разных потоков
  • использовать разные случайные экземпляры на поток
  • Любой из них может подойти; но мьютекс одного единственного экземпляра от нескольких вызывающих абонентов в одно и то же время просто вызывает проблемы.

    Блокировка обеспечивает первый (и более простой) из этих подходов; однако, другой подход может быть следующим:

    private static readonly ThreadLocal<Random> appRandom
         = new ThreadLocal<Random>(() => new Random());
    

    это тогда для каждого потока, поэтому вам не нужно синхронизировать.

    t получить к нему доступ одновременно из разных потоков
  • использовать разные случайные экземпляры на поток
  • Любой из них может подойти; но мьютекс одного единственного экземпляра от нескольких вызывающих абонентов в одно и то же время просто вызывает проблемы.

    Блокировка обеспечивает первый (и более простой) из этих подходов; однако, другой подход может быть следующим:

    private static readonly ThreadLocal<Random> appRandom
         = new ThreadLocal<Random>(() => new Random());
    

    это тогда для каждого потока, поэтому вам не нужно синхронизировать.

    1009
    ответ дан 22 November 2019 в 21:28
    поделиться

    1) Как сказал Марк Гравелл, попробуйте использовать ОДИН генератор случайных чисел. Всегда здорово добавить это в конструктор: System.Environment.TickCount.

    2) Один совет. Допустим, вы хотите создать 100 объектов и предположить, что у каждого из них должен быть свой собственный генератор случайных чисел (удобно, если вы вычисляете НАГРУЗКИ случайных чисел за очень короткий период времени). Если бы вы делали это в цикле (создание 100 объектов), вы могли бы сделать это так (чтобы обеспечить полную случайность):

    int inMyRandSeed;
    
    for(int i=0;i<100;i++)
    {
       inMyRandSeed = System.Environment.TickCount + i;
       .
       .
       .
       myNewObject = new MyNewObject(inMyRandSeed);  
       .
       .
       .
    }
    
    // Usage: Random m_rndGen = new Random(inMyRandSeed);
    

    Приветствия.

    14
    ответ дан 3 revs, 3 users 88% 22 March 2017 в 16:19
    поделиться

    просто объявите переменную класса Random следующим образом:

        Random r = new Random();
        // ... Get three random numbers.
        //     Here you'll get numbers from 5 to 9
        Console.WriteLine(r.Next(5, 10));
    

    , если вы хотите каждый раз получать разные случайные числа из своего списка, используйте

    r.Next(StartPoint,EndPoint) //Here end point will not be included
    

    Каждый раз, объявив Random r = new Random() один раз.

    1
    ответ дан Abdul 22 March 2017 в 16:19
    поделиться

    Я бы лучше использовал следующий класс для генерации случайных чисел:

    byte[] random;
    System.Security.Cryptography.RNGCryptoServiceProvider prov = new System.Security.Cryptography.RNGCryptoServiceProvider();
    prov.GetBytes(random);
    
    24
    ответ дан 22 November 2019 в 21:28
    поделиться

    Решение Марка может быть довольно дорогим, так как оно требует синхронизации каждый раз.

    Мы можем обойти необходимость синхронизации, используя шаблон хранения для конкретного потока:

    
    public class RandomNumber : IRandomNumber
    {
        private static readonly Random Global = new Random();
        [ThreadStatic] private static Random _local;
    
        public int Next(int max)
        {
            var localBuffer = _local;
            if (localBuffer == null) 
            {
                int seed;
                lock(Global) seed = Global.Next();
                localBuffer = new Random(seed);
                _local = localBuffer;
            }
            return localBuffer.Next(max);
        }
    }
    
    

    Измерьте две реализации и вы должны увидеть значительную разницу.

    61
    ответ дан 22 November 2019 в 21:28
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: