Как сделать так, чтобы долгое ожидание запускалось - PullRequest
0 голосов
/ 04 мая 2018

Я работаю в ядре 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 Ответ

0 голосов
/ 04 мая 2018

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();
    }
}
...