Other threads stop when one thread reaches its destination

I am currently working on understanding the concept of Java multithreading. I went through a tutorial that uses an example of turtles and a plot to explain the concept of multithreading, and to a large extent I understood the syntax and logic of the video tutorial. At the end of the video tutorial, Youtuber gave an assignment that involved applying Multithreading to an Olympic race track.

Using my knowledge from the example, I was able to create 10 threads (representing athletes) that run in a loop that runs 100 times (which is 100 meters).

My task is that when the thread planner makes an athlete to get to 100 meters in front of the other 9 athletes, the remaining 9 threads always do not complete their race. This usually does not apply to a standard race track. The fact that the thread called Usain Bolts reaches 100 does not mean that Johan Blake should stop working if he reaches 90 meters at that time.

I am also interested in getting the distance (note that they all use the same variable) for each thread, so I can use the function to return the positions of each thread at the end of the race.

What I did (this did not work): 1) I tried to use the if else construct (containing nine "else" statements) to assign the distance of each executable stream to a new integer variable. (using the property Thread.currentThread (). getName () and the name of each thread), but this did not help me. It was an attempt to give positions only to athletes using their distance, but does nothing about 9 athletes who do not finish the race.
2) I also tried using ArrayList to fill the distance at runtime, but for some strange reason, it still overwrites the distance every time it wants to add another distance.

Below are my codes:

package olympics100meters; import java.util.ArrayList; public class HundredMetersTrackRules implements Runnable { public static String winner; public void race() { for (int distance=1;distance<=50;distance++) { System.out.println("Distance covered by "+Thread.currentThread ().getName ()+" is "+distance+" meters."); boolean isRaceWon=this.isRaceWon(distance); if (isRaceWon) { ArrayList<Integer> numbers = new ArrayList(); numbers.add(distance); System.out.println("testing..."+numbers); break; } } } private boolean isRaceWon(int totalDistanceCovered) { boolean isRaceWon=false; if ((HundredMetersTrackRules.winner==null)&& (totalDistanceCovered==50)) { String winnerName=Thread.currentThread().getName(); HundredMetersTrackRules.winner=winnerName; System.out.println("The winner is "+HundredMetersTrackRules.winner); isRaceWon=true; } else if (HundredMetersTrackRules.winner==null) { isRaceWon=false; } else if (HundredMetersTrackRules.winner!=null) { isRaceWon=true; } return isRaceWon; } public void run() { this.race(); } } 

This is my main method (I reduced it to 5 athletes until I figured out the problems):

 public class Olympics100Meters { /** * @param args the command line arguments */ public static void main(String[] args) { HundredMetersTrackRules racer=new HundredMetersTrackRules(); Thread UsainBoltThread=new Thread(racer,"UsainBolt"); Thread TysonGayThread=new Thread (racer,"TysonGay"); Thread AsafaPowellThread=new Thread(racer,"AsafaPowell"); Thread YohanBlakeThread=new Thread (racer,"YohanBlake"); Thread JustinGatlinThread=new Thread (racer,"JustinGatlin"); UsainBoltThread.start(); TysonGayThread.start(); AsafaPowellThread.start(); YohanBlakeThread.start(); JustinGatlinThread.start(); } } 
+5
source share
2 answers
  • My problem is that ... the remaining 9 threads do not always finish their race.

This is caused by the implementation of the isRaceWon() method. You check it on every meter of every runner. As soon as the first runner reaches 100 meters, break is called in the next step of each runner cycle (the race is won for each cycle

btw, it makes sense to use volatile statuc String for the name of the winner to avoid the ambiguity of the java memory model.

  1. I am also interested in getting distance ... for each thread, so I can use the function to return the positions of each thread at the end of the race.

If the final goal is to get a position, create a class field public List<String> finishingOrder = new ArrayList<String> and finish method

 private synchronized finish() { finishingOrder.add(Thread.currentThread().getName()) } 

and call it after the run loop

don't forget to call join() for all running threads in main . After that, finishingOrder will contain the names in order of completion.

0
source

The following code snippet causes isRaceWon return true for each instance of HundredMetersTrackRules as soon as the shared winner field is set to non-null (i.e., someone wins.):

 else if (HundredMetersTrackRules.winner!=null) { isRaceWon=true; } 

This in turn causes the cycle in race() break for each instance of your Runnable . The run() method completes the completion of a thread.

The problem is just a logical error and not very specific to streaming. But, as mentioned in other posters, this code has several advanced streaming methods, for example, using volatile for fields shared by streams.

0
source

Source: https://habr.com/ru/post/1232732/


All Articles