Question:
I have a main class with an array of threads, which are responsible for making changes to the objects of the arrayList
that I pass as a parameter.
Now what I need is another thread that is in charge of displaying the data of the objects while they are being modified, so that I can see the modification. Obviously the thread that displays data will go faster than the one that modifies.
public class Principal {
public static void main(String[] args) {
final int ROOMS = 10;
final int VIS = 7;
final int GROUP = 7;
Semaphore SEM = new Semaphore(GROUP);
Visitante hiloVisitador[] = new Visitante[VIS];
ArrayList<Room> sala = new ArrayList();
for (int i = 0; i < ROOMS; i++) {
String reg[] = new String[GROUP];
for (int j = 0; j < GROUP; j++) {
reg[j] = " ";
}
//array list de objetos
sala.add(new Room(String.valueOf(i + 1), reg));
}
//array de hilos, se encargan de realizar modificaciones sobre los objetos de la lista
for (int i = 0; i < VIS; i++) {
hiloVisitador[i] = new Visitante(String.valueOf(i + 1), sala, SEM);
hiloVisitador[i].start();
}
try {
for (int i = 0; i < VIS; i++) {
hiloVisitador[i].join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I don't know where to put another thread, that's my question.
I clarify: I do not use code for my exercise (I can develop it), I only know if this is possible and if so, where to put it, before the Visitador
thread, after, etc.
Answer:
You seem to have a Visitante
class that extends from Thread
(denoted by hiloVisitador[i].start()
). You have many ways to add a thread that does other work with the objects you have:
-
Create an anonymous
Runnable
instance that does the job and pass it as a parameter in theThread
constructor:Thread t = new Thread( () -> { //aquí va la definición del método run }); t.start();
-
Create a class that implements
Runnable
and pass an instance of this class in theThread
class's constructor:public class Mostrador implements Runnable { //definición de la clase... @Override public void run() { //lógica para mostrar los datos } } //dentro del método main Thread t = new Thread(new Mostrador(/*quizás pongas argumentos aquí*/)); t.start();
-
Similar to above, but extending from
Thread
(similar to yourVisitante
class):public class Mostrador extends Thread { //definición de la clase... @Override public void run() { //lógica para mostrar los datos } } //dentro del método main Thread t = new Mostrador(/*quizás pongas argumentos aquí*/); t.start();
Since you already have an array of Visitante
s, I would recommend changing it to an array of Thread
s since you don't use anything else of that class, and the size of the array allows 1 more element to hold this new manually created Thread
instance:
Thread hilos[] = new Visitante[VIS+1];
for (int i = 0; i < VIS; i++) {
hilos[i] = new Visitante(String.valueOf(i + 1), sala, SEM);
hilos[i].start();
}
//descomentar de acuerdo a lo que escojas
//si usas la forma 1
//hilos[VIS] = new Thread( () -> {
// });
//si usas la forma 2
//hilos[VIS] = new Thread(new Mostrador(/* argumentos */));
//si usas la forma 3
//hilos[VIS] = new Mostrador(/* argumentos */);
hilos[VIS].start();
try {
for (int i = 0; i < VIS+1; i++) {
hiloVisitador[i].join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
I don't use code for my exercise (I can develop it), I only know if this is possible and if so, where to put it, before the Visitor thread, after, etc.
This is irrelevant since when executing Thread#start
one thread will not necessarily start its execution before another. This will be decided by the operating system based on the use of the processors. You can put the thread before or after the array elements, the result shouldn't affect it. Now, consider that if you use collections inside your methods eg List
, Map
, Set
, then make sure you use implementations that support concurrency eg ArrayList
doesn't support concurrency, instead you can use CopyOnWriteArrayList
, and so there are other implementations for these collections you can check out in the java.util.concurrent
package documentation.
Now, this solution is not so elegant. Instead I would recommend using ExecutorService
which will manage the threads for you and you focus only on the tasks that should be executed in parallel.