BG Development


Страници: (7) 1 2 [3] 4 5 ... последна »  ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> Java Threads щафета
bvbfan
Публикувано на: 24-10-2015, 09:18
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2893
Регистриран на: 08.12.13



Струва ми се странно и нелогично, след като ползват С апи-то, да правят нотификация към случайна нишка.


--------------------
QUOTE (Bender @ 23-04-2015, 19:11)
Xamarin: ЛАПАЙ!
Ти: Добре...
PMEmail Poster
Top
FidelDahan
Публикувано на: 24-10-2015, 10:04
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2345
Регистриран на: 12.06.08



Интересно, че в POSIX гарантират последователност. Но даже и в Java да беше така, мисля че не е достатъчно да се разчита само на нея, защото къде е гаранцията, че тредовете ще достигнат монитора в последователността в която са били стартирани?

Извинявам се за пресиленото исказване относно обучението. Може би наистина е по-добре първо да се изучат примитивите и после да се мине на по-високи абстракции от рода на CountDownLatch, Exchanger, CyclicBarrier. Проблема с wait() и notify() е че с тях най-трудно се реализира коректно поведение и често нещата се оплитат. Но от тази гледна точка може би е полезно за учащия, който така вижда, че нещата при многонишковото програмиране не са прости.
PMEmail Poster
Top
bvbfan
Публикувано на: 24-10-2015, 10:11
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2893
Регистриран на: 08.12.13



Реализацията на въпросните високи абстракции е с condition_variable, но не правилното му използване може да доведе до манджа. Високите абстракции не са панацея, но в много случаи са по-доброто решение.


--------------------
QUOTE (Bender @ 23-04-2015, 19:11)
Xamarin: ЛАПАЙ!
Ти: Добре...
PMEmail Poster
Top
ivan84
Публикувано на: 24-10-2015, 11:36
Quote Post



Име:
Група: Форумен член
Ранг: Почетен член

Мнения: 8170
Регистриран на: 01.04.11



QUOTE (bvbfan @ 24-10-2015, 10:18)
Струва ми се странно и нелогично, след като ползват С апи-то, да правят нотификация към случайна нишка.

Е то случайни работи няма. Все има някакъв критерий, ама дали ще е първата или последната нишка (зависи дали ползват стек или опашка в имплементацията) не се знае. Може да има значение приоритетът и т.н. Затова и казват "нотифицира една нишка" без да се конкретизира коя.

Виж оригиналното решение на ОП, явно се ползва опашка и наистина се нотифицира първата нишка стигнала до мониторът (ако приемем, че наистина работи коректно). Но да се гарантира, че първата създадена нишка ще е първата стигнала до тоя монитор е сложно. Решението със sleep което е ползвал ми се струва ненадеждно.
PMEmail Poster
Top
bvbfan
Публикувано на: 24-10-2015, 11:50
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2893
Регистриран на: 08.12.13



Sleep е най-лошото възможно решение, аз го избягвам винаги, когато е възможно.


--------------------
QUOTE (Bender @ 23-04-2015, 19:11)
Xamarin: ЛАПАЙ!
Ти: Добре...
PMEmail Poster
Top
FidelDahan
Публикувано на: 24-10-2015, 11:53
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2345
Регистриран на: 12.06.08



QUOTE (ivan84 @ 24-10-2015, 07:25)
Има ли начин да се реши задачата точно по условието? В смисъл, синхронизация на няколко нишки по общ обект, които да се нотифицират една по една с notify, но все пак да се спазва някакъв ред.

Би било по-лесно с 4 монитора, един за всеки атлет или пък ако може да се използва notifyAll(). Ако е такова условието - само един обект който служи за монитор и само notify() нещата стават сложни. Признавам, даде ми малко зор докато стане коректно:

CODE
import java.util.Random;

class Token {
 private int athleteNumber = 0;

 boolean isAssignedTo(int athleteNumber) {
   return this.athleteNumber == athleteNumber;
 }

 void assignToNext() {
   this.athleteNumber++;
 }
}

class Athlete extends Thread {
 private static final Random random = new Random();
 private final int number;
 private final Token token;
 private volatile boolean ready = false;

 public Athlete(int number, Token token) {
   this.number = number;
   this.token = token;
 }

 @Override
 public void run() {
   try {
     this.ready = true;
     System.out.println("Ready " + this.number);
     acquireTokenBeforeStart();
     System.out.println("Starting " + this.number);
     Thread.sleep(1000 + random.nextInt(1000));
     System.out.println("Finishing " + this.number);
     releaseTokenAfterFinish();
   }
   catch (InterruptedException ex) {
     ex.printStackTrace();
     Thread.currentThread().interrupt();
   }
 }

 public boolean isReady() {
   return ready;
 }

 private void acquireTokenBeforeStart() throws InterruptedException {
   synchronized (token) {
     token.wait();
     while (!token.isAssignedTo(this.number)) {
       token.notify();
       token.wait();
     }
   }
 }

 private void releaseTokenAfterFinish() {
   synchronized (token) {
     token.assignToNext();
     token.notify();
   }
 }
}

public class Relay {
 private final Token token = new Token();
 private final Athlete a0 = new Athlete(0, token);
 private final Athlete a1 = new Athlete(1, token);
 private final Athlete a2 = new Athlete(2, token);
 private final Athlete a3 = new Athlete(3, token);

 private void letAthletesPrepareForRace() {
   a0.start();
   a1.start();
   a2.start();
   a3.start();
 }

 private void awaitAthletesToBecomeReady() {
   while (!(a0.isReady() && a1.isReady() && a2.isReady() && a3.isReady())) {
     Thread.yield();
   }
 }

 private void triggerRaceAndLetAthletesRun() {
   synchronized (token) {
     token.notify();
   }
 }

 public static void main(String[] args) throws Exception {
   Relay relay = new Relay();
   relay.letAthletesPrepareForRace();
   relay.awaitAthletesToBecomeReady();
   relay.triggerRaceAndLetAthletesRun();
 }
}


CODE
Ready 1
Ready 3
Ready 0
Ready 2
Starting 0
Finishing 0
Starting 1
Finishing 1
Starting 2
Finishing 2
Starting 3
Finishing 3

Process finished with exit code 0
PMEmail Poster
Top
ivan84
Публикувано на: 24-10-2015, 12:08
Quote Post



Име:
Група: Форумен член
Ранг: Почетен член

Мнения: 8170
Регистриран на: 01.04.11



Ако първоначалното условие е вярно, то май това се иска. Е ще трябва да си го пипне за да се синхронизира по гол Object но идеята е важна.
PMEmail Poster
Top
FidelDahan
Публикувано на: 24-10-2015, 12:21
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2345
Регистриран на: 12.06.08



Сега разбрах и твоята идея със опашката, go(), notifyAll и флагът notify.
PMEmail Poster
Top
JanBirdX
Публикувано на: 24-10-2015, 18:12
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1543
Регистриран на: 21.02.05



Не мога да разбера защо усложняавате нещата:
CODE
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

   static class Athlete implements Runnable{

       private long sleepTime;

       public Athlete(long sleepTime){
           this.sleepTime = sleepTime;
       }

       @Override
       public void run() {
           try {
               Thread.sleep(sleepTime);
           } catch (InterruptedException e) {
           }
       }
   }

   public static void main(String[] args) {
       ExecutorService executorService = Executors.newSingleThreadExecutor();

       executorService.submit(new Athlete(1000));
       executorService.submit(new Athlete(3000));
       executorService.submit(new Athlete(9000));
       executorService.submit(new Athlete(8000));
   }
}
PMEmail Poster
Top
felore
Публикувано на: 24-10-2015, 20:44
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3872
Регистриран на: 22.10.09



Евалата, Жан, готино и семпло решение, но от никого не видях да се предава "щафета", т.е. стойност от едната нишка на другата.

Ред: не се заяждам, интересно ми е как би станало.

Това мнение е било редактирано от felore на 24-10-2015, 20:46


--------------------
PMEmail Poster
Top
0 потребители преглеждат тази тема в момента (0 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (7) 1 2 [3] 4 5 ... последна » Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2018 | BG Development | All Rights Reserved
RSS 2.0