Getting a value / Returning something every time a thread executes its run

I have 2 threads. One of them is TimeStepThread , the other is CarThread . CarThread runs every 500 ms. TimeStepThread works in any interval that I give it. Now, every 500 ms, CarThread updates the movement of vehicle positions on the road. Every time TimeStepThread is TimeStepThread , I want to get this car position value. For example, I have 1 car that is updated every 500 ms no matter what, but every 2 seconds I want to set a mark with this position of the car.

My classes are configured as follows:

  • Simulation class has
  • TimeStepThread and CarThread .

In my Simulation (or in the frame, rather) I want to update the value of the position of the car at each time interval. Therefore, every 2000 ms I need to update / return something to the Simulation class.

In addition, I do not know how to do this. Since my threads are inside Simulation , I cannot name the Simulation method from run() , not to mention that it will be a bit messy. Listeners, maybe?


Edit: I can already access the machines in the timestep stream. It's not a problem. I use a container class that contains cars, both threads can access, and CarThread also updates it. My problem is that the Simulation class has an updated String, every time a TimeStepThread is called or a Frame label is updated, every time a TimeStepThread is called.

+4
source share
4 answers

Two classes, those in two streams, need access to the list of cars.

In this case, cars are instances of a car class.

The flow of time steps has a class that implements its work. (Which reads the positions of cars.)

There is a class in carving that does its job. (Which updates line items.)

Each runtime class will access the vehicleโ€™s objects to either update them with corrections information or read anything. You will need to synchronize use instance methods in the car class (or the container for cars mentioned below) that access the position, for example, so that different threads do not step on each other.

There are two similar implementation methods here.

1) Each time you create a car, you pass it to each of the two working classes. Each of them maintains its own list of all vehicles. If you get rid of the car, you must tell them both.

2) At the beginning, you give each of the two working classes a link to the container class for cars. Maybe just a list - a parallel list. Maybe a custom class. When you create a car, you specify the class of the container of the car (adding it). When you lose a car, you also talk about it.

As for the Simulation class, you want it to be informed of a change in vehicle position. Again there are two ways, but they are similar.

In both cases, you will have to pass an instance of the modeling class to the class that is performing the update. The simulation class has a method, such as updateCar() , which calls the update class after the update is completed.

1) Version 1 - a call to an instance of the simulation class indicates only that something has changed. The code in the modeling class will determine what has changed and what is connected with it, or it will just update everything.

2) Version 2 - a call to an instance of the simulation class will contain a list of any cars that have been changed. A modeling class does not have to search to find what has changed and it can only update changes.

The tricky part is that you have to remember that calls to this update method occur in the update stream. For example, if you use Swing to update the text on the screen, you will need to use SwingWorker to receive updates in the event stream.

If you cannot move this work to a safe thread, you need to make sure that all the right things are parallel or synchronized, so they don't step on each other.

+1
source

You can put ConcurrentLinkedQueue in the Simulation class - the Car thread sends queue position updates. Then the Timestep thread processes all position updates ( poll queue until it is empty) and places labels.

Alternatively, you can put a BlockingQueue in the Simulation class and constantly keep the take stream from the queue and update the location information.

Thus, you can add as many additional cars as possible without having to change the Simulation code - all cars send their updates in the same queue.

0
source

I think a listener for your automotive progress is the best approach. You could be something like

 public interface CarProgressListener { void positionChanged(Position currentPosition); } 

then create TimestepThread this interface and register it in CarThread .

 public CarThread extends Thread { private final Collection<CarProgressListener> progressListeners = new LinkedList<>(); // other stuff public void addListener(CarProgressListener listener) { this.progressListeners.add(listener); } } public TimestepThread extends Thread implements CarProgressListener { private Position lastHeardCarPosition; // remenber to initiate this thread with the first car position. @Override public void positionChanged(Position currentPosition) { this.lastHeardCarPosition = currentPosition; } } 

So, now in your Simulation class you will need something like

 ... Position initialPosition = // get it from somewhere. CarThread car = new CarThread(initialPosition); TimestepThread timestepThread = new TimestepThread(initialPosition); car.addListener(timestepThread); ... 
0
source

I donโ€™t think you need a list or any other data structure. It could be that simple:

 public class Car private volatile int position; public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } } public class CarThread extends Thread { private final Car car; public CarThread(Car car) { this.car = car; } @Override public void run() { Thread.sleep(500); car.setPosition(//whatever) } } public class TimeStepThread extends Thread { private final Car car; public CarThread(Car car) { this.car = car; } @Override public void run() { Thread.sleep(2000); int position = car.getPosition() // do stuff } } 

Make sure that you transfer the same copy of the car to everything and everything will be in order.

This answer also suggests that you do not need to queue all position changes, that only the most recent position is of interest, which if you use it to draw a carโ€™s location on a map or something else seems reasonable.

EDIT

To put it all together, try something like this:

 public class TimeStepThread extends Thread { private final Car car; private final JFrame frame; public TimeStepThread(Car car, JFrame frame) { this.car = car; this.frame = frame; } @Override public void run() { while(true) { Thread.sleep(2000); EventQueue.invokeLater(new Runnable() { @Override public void run() { frame.setTitle(Integer.toString(car.getPosition())); } } } } } 
0
source

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


All Articles