notifyAll как только все потоки станут WAITING

 
 
 
Сообщения:49
Добрый день!
public class Notify1 {	
	public static void main(String[] args) throws InterruptedException {
		MyTask1 myTask = new MyTask1();
		Runnable taskInstance1 = () -> myTask.doWorkI_1();
		Runnable taskInstance2 = () -> myTask.doWorkI_2();
		Runnable taskInstance3 = () -> myTask.doWorkI_1();
		Runnable taskInstance4 = () -> myTask.doWorkI_2();		
		
		Thread potok1 = new Thread(taskInstance1);
		Thread potok2 = new Thread(taskInstance2);
		Thread potok3 = new Thread(taskInstance3);
		Thread potok4 = new Thread(taskInstance4);
		
		potok1.start();
		potok2.start();
		potok3.start();
		potok4.start();	
		
		synchronized(myTask) {
			myTask.notifyAll();
		}		
	}	
}

class MyTask1 {	
	public synchronized  void doWorkI_1() {			
			try {
				System.out.println(Thread.currentThread().getId() + ": enter in doWorkI_1 ");
				wait();
				System.out.println(Thread.currentThread().getId() + ": done after wait doWorkI_1");				
			} catch (InterruptedException e) {}		
	}
	
	public synchronized   void doWorkI_2() {	
			try {
				System.out.println(Thread.currentThread().getId() + ": enter in doWorkI_2 ");			
				wait();
				System.out.println(Thread.currentThread().getId() + ": done after wait doWorkI_2");				
			} catch (InterruptedException e) {}		
	}
}


Если запустить как есть то в main метод notifyAll() может выполниться раньше чем все потоки успеют дойти до метода wait(). Что приведет к зависанию.

если я вставлю в main строчку Thread.sleep(100); перед синхронизированным блоком, то это решит проблему , но получается будет время простоя всей программы.

если я вставлю скажем цикл с бесконечной проверкой состояния этих 4-х потоков
        while(true) {
			System.out.println("check");
			if(	potok1.getState() == Thread.State.WAITING && 
				potok2.getState() == Thread.State.WAITING && 
				potok3.getState() == Thread.State.WAITING &&
				potok4.getState() == Thread.State.WAITING )
				break;
		}		

		synchronized(myTask) {
			myTask.notifyAll();
		}

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

А как изящно решить задачу, чтобы когда последний из потоков уйдет в статус WAITING сразу в main исполнился метод notifyAll() ? Без CyclicBarrier и им подобных, оставаясь в рамках пакета lang
Изменен:11 авг 2019 13:24
 
 
Сообщения:268
А что если стартовать потоки уже внутри synchronized блока, а потом поставить 4 вэйта.
Ну и из потоков слать нотифай перед вэйтом.
Изврат конечно, но может сработать =)

"Мы же профессионалы! Мы всегда делаем чуть больше, чем требуется!" (с)
 
 
Сообщения:49
MuH3gPaB, не могли бы привести код , не пойму ))
Изменен:12 авг 2019 07:49
 
 
Сообщения:268
А... не, не получится так...

Можно тогда попробовать еще один изврат =)

synchronized(potok1) {
   potok1.start(); potok1.wait();
}


а внутри делать
Thread.currentThread().notify();

"Мы же профессионалы! Мы всегда делаем чуть больше, чем требуется!" (с)
 
 
Сообщения:49
Quote:
а внутри делать

внутри класса MyTask1 ? Не, будем считать что это класс мы не можем менять никак ))
 
 
Сообщения:453
krogot88:
Не, будем считать что это класс мы не можем менять никак ))

тогда нет гарантий, что 100% будет работать этот костылезавр: Notify1 никак не узнает, кто там wait, а кто нет
 
 
Сообщения:268
Можно еще пробежать по всем тредам с `getState()`

"Мы же профессионалы! Мы всегда делаем чуть больше, чем требуется!" (с)
 
 
Сообщения:49
MuH3gPaB:
Можно еще пробежать по всем тредам с `getState()`

это делать цикл который n-раз успеет отработать вхолостую пока все 4 потока упрутся в wait. А нам нужно чтобы сразу по какому-то триггеру
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет