Как сделать так, чтобы долгое ожидание запускалось

Я работаю в ядре Java. У меня есть одна небольшая программа, которая будет печатать числа 1,2,3 соответствующими потоками thread1, thread2 и thread3.

while(true)
        {
            synchronized (obj)
            {

                System.out.println("Thread got chance : "+Thread.currentThread().getName());


                if (ai.get() ==0 && Thread.currentThread().getName().equalsIgnoreCase("Thread1"))
                {
                    System.out.print(ai.incrementAndGet()+"("+Thread.currentThread().getName()+")"+" ");
                    obj.notify();
                    obj.wait();
                }

                if (ai.get() ==1 && Thread.currentThread().getName().equalsIgnoreCase("Thread2"))
                {
                    System.out.print(ai.incrementAndGet()+"("+Thread.currentThread().getName()+")"+" ");
                    obj.notify();
                    obj.wait();
                }

                if (ai.get() ==2 && Thread.currentThread().getName().equalsIgnoreCase("Thread3"))
                {
                    System.out.print(ai.incrementAndGet()+"("+Thread.currentThread().getName()+")"+" ");
                    System.out.println("");
                    ai.set(0);
                    obj.notify();
                    obj.wait();
                }

            }

        }

в приведенной выше программе логика в порядке и работает, т.е. она печатает по порядку. Но я напечатал название нити с "Нить получила изменение". то есть я пытался определить, какой поток получает больше шансов на запуск, и узнал имя потока Ex thread 2.

Вопрос в том, "Как я могу убедиться, что все потоки получают одинаковые шансы. Поскольку это небольшая программа, поток выполнит свою работу и выйдет в течение миллисекунд, а мы не узнаем. Что, если поток занимает немного долго бегать "?

Пожалуйста помоги.

1 ответ

synchronized не поддерживает fair политика. Любой ожидающий поток может быть разбужен, когда вы звоните notify(),

Вы можете использовать ярмарку ReentrantLock:

  • Когда вы звоните lock() самый длинный ожидающий поток получит блокировку.
  • Когда вы звоните signal(), самый длинный ожидающий поток будет сигнализироваться первым.

Это пример кода:

// Use the same lock and condition in different threads
ReentrantLock lock = new ReentrantLock(true);  // create a fair lock
Condition condition = lock.newCondition();

while (true) {
    lock.lock();
    try {
        System.out.println("Thread got chance : " + Thread.currentThread().getName());

        if (ai.get() == 0 && Thread.currentThread().getName().equalsIgnoreCase("Thread1")) {
            System.out.print(ai.incrementAndGet() + "(" + Thread.currentThread().getName() + ")" + " ");
            condition.signal();
            condition.await();
        }

        if (ai.get() == 1 && Thread.currentThread().getName().equalsIgnoreCase("Thread2")) {
            System.out.print(ai.incrementAndGet() + "(" + Thread.currentThread().getName() + ")" + " ");
            condition.signal();
            condition.await();
        }

        if (ai.get() == 2 && Thread.currentThread().getName().equalsIgnoreCase("Thread3")) {
            System.out.print(ai.incrementAndGet() + "(" + Thread.currentThread().getName() + ")" + " ");
            System.out.println("");
            ai.set(0);
            condition.signal();
            condition.await();
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}
Другие вопросы по тегам