У меня есть 2 матрицы, и мне нужно их умножить, а затем распечатать результаты каждой ячейки. Как только одна ячейка будет готова, мне нужно ее распечатать, но, например, мне нужно распечатать ячейку [0] [0] перед ячейкой [2] [0], даже если результат [2] [0] готов первым , Поэтому мне нужно распечатать его по заказу. Итак, моя идея состоит в том, чтобы заставить поток принтера ждать, пока multiplyThread
он не уведомит его о том, что правильная ячейка готова к печати, а затем printerThread
распечатает ячейку и вернется в режим ожидания и так далее.
Итак, у меня есть этот поток, который выполняет умножение:
public void run()
{
int countNumOfActions = 0; // How many multiplications have we done
int maxActions = randomize(); // Maximum number of actions allowed
for (int i = 0; i < size; i++)
{
result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
countNumOfActions++;
// Reached the number of allowed actions
if (countNumOfActions >= maxActions)
{
countNumOfActions = 0;
maxActions = randomize();
yield();
}
}
isFinished[rowNum][colNum] = true;
notify();
}
Поток, выводящий результат каждой ячейки:
public void run()
{
int j = 0; // Columns counter
int i = 0; // Rows counter
System.out.println("The result matrix of the multiplication is:");
while (i < creator.getmThreads().length)
{
synchronized (this)
{
try
{
this.wait();
}
catch (InterruptedException e1)
{
}
}
if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
{
if (j < creator.getmThreads()[i].length)
{
System.out.print(creator.getResult()[i][j] + " ");
j++;
}
else
{
System.out.println();
j = 0;
i++;
System.out.print(creator.getResult()[i][j] + " ");
}
}
}
Теперь это выдает мне следующие исключения:
Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
строка 49 multiplyThread
- это «notify ()» .. Я думаю, мне нужно использовать синхронизированный код по-другому, но я не уверен, как это сделать.
Если кто-то может помочь этому коду работать, я буду очень признателен.
источник
while(!JobCompleted);
вариант, как правило, плохая идея, потому что он заставляет ваш процессор на 100% постоянно проверять одну и ту же переменную (см. Здесь )while(!JobCompleted) Thread.sleep(5);
нет такой проблемыwait
всякий раз, когда текущий поток блокирует объект, которыйwait
вызывается. Независимо от того, используете ли выsynchronized
блочный или синхронизированный метод, все зависит от вас.При использовании методов
wait
иnotify
илиnotifyAll
в Java необходимо помнить следующее:notifyAll
вместо,notify
если вы ожидаете, что более одного потока будут ожидать блокировки.wait
иnotify
методы должны быть вызваны в синхронном контексте . См. Ссылку для более подробного объяснения.wait()
метод в цикле, потому что, если несколько потоков ожидают блокировки, и один из них получил блокировку и сбросил условие, тогда другие потоки должны проверить условие после того, как они проснутся, чтобы узнать, нужно ли им снова ждать или можно начать обработку.wait()
иnotify()
метода; у каждого объекта есть собственная блокировка, поэтому вызовwait()
объекта A иnotify()
объекта B не имеет смысла.источник
Вам вообще нужно это нить? Мне интересно, насколько велики ваши матрицы, и есть ли какая-то польза от печати одним потоком, в то время как другой выполняет умножение.
Возможно, стоит измерить это время, прежде чем выполнять относительно сложную работу с потоками?
Если вам действительно нужно его распределять, я бы создал n потоков для выполнения умножения ячеек (возможно, n - это количество доступных вам ядер), а затем использовал бы ExecutorService и механизм Future для одновременной отправки нескольких умножений ,
Таким образом, вы можете оптимизировать работу в зависимости от количества ядер, и вы используете инструменты потоковой передачи Java более высокого уровня (которые должны облегчить жизнь). Запишите результаты обратно в приемную матрицу, а затем просто распечатайте ее, когда все ваши будущие задачи будут выполнены.
источник
Допустим, у вас есть приложение «черный ящик» с некоторым классом
BlackBoxClass
, имеющим методdoSomething();
.Кроме того, у вас есть названный наблюдатель или слушатель,
onResponse(String resp)
который будет вызванBlackBoxClass
через неизвестное время.Схема проста:
Допустим, мы не знаем, что происходит
BlackBoxClass
и когда мы должны получить ответ, но вы не хотите продолжать свой код, пока не получите ответ или, другими словами, неonResponse
позвоните. Здесь вводится «Помощник по синхронизации»:Теперь мы можем реализовать то, что хотим:
источник
Вы можете вызвать уведомление только для объектов, монитор которых у вас есть. Итак, вам нужно что-то вроде
источник
notify()
также необходимо синхронизироватьисточник
Я прямо сейчас на простом примере покажу, как правильно использовать
wait
иnotify
в Java. Итак, я создам два класса с именами ThreadA и ThreadB . ThreadA вызовет ThreadB.и для класса ThreadB:
источник
Простое использование, если вы хотите Как альтернативно выполнять потоки: -
источник
мы можем вызвать notify, чтобы возобновить выполнение ожидающих объектов, как
возобновить это, вызвав уведомление для другого объекта того же класса
источник
Для этой конкретной проблемы почему бы не сохранить ваши различные результаты в переменных, а затем, когда последний из вашего потока будет обработан, вы можете распечатать в любом формате, который вы хотите. Это особенно полезно, если вы собираетесь использовать свою историю работы в других проектах.
источник
Это похоже на ситуацию для модели производитель-потребитель. Если вы используете java 5 или более позднюю версию, вы можете рассмотреть возможность использования очереди блокировки (java.util.concurrent.BlockingQueue) и оставить работу по координации потоков для реализации базового фреймворка / api. См. Пример из java 5: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html или java 7 (тот же пример): http: // docs. oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
источник
Вы правильно защитили свой блок кода при вызове
wait()
метода с помощьюsynchronized(this)
.Но вы не приняли такой же меры предосторожности при вызове
notify()
метода без использования защищенного блока:synchronized(this)
илиsynchronized(someObject)
Если вы обратитесь к оракул странице документации на Объект класса, который содержит
wait()
,notify()
,notifyAll()
методы, вы можете увидеть ниже меры предосторожности во всех этих трех методовЗа последние 7 лет многое изменилось, и давайте рассмотрим другие альтернативы
synchronized
в следующих вопросах SE:Зачем использовать ReentrantLock, если можно использовать synchronized (this)?
Синхронизация против блокировки
Избегайте синхронизации (этого) в Java?
источник