How do you force threads to perform certain functions?

Asked

Viewed 78 times

1

10 threads are agreed when the Client connects to the server, when the Client asks for a word, The server wakes up these threads and they will go through a list of tasks.

What I wanted to happen: whenever a thread scans that word, it removes that task from the list so that when the next one runs this task it is no longer in the list.

What happens: more than one thread starts to scan(), and they all scan() the first task.

public  class ThreadSearcher extends Thread{
    private int x;

    public ThreadSearcher(int x){
        this.x=x;   

    }


    @Override
    public void run(){

        while(!interrupted()){

            System.out.println("Comecei a correr:" + x); 
            try {

                Tarefa t = getTarefas().get(0);
                scan(t);
                System.out.println("Sou a "+ this.x + " e fiz o scan de " + t.getStart() + "a" + t.getFinish());
                System.out.println("Sou a " + x + "antes de remover tinha " + tarefas.size());
                tarefas.remove(t);
                System.out.println("Sou a " + x + "depois de remover tinha " + tarefas.size());

                System.out.println("removi a" + t);



            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



        }
    }
}
  • Enter the code of your class Tarefa and the class where you create your ThreadSearcher, please.

1 answer

2


This is a common multithreading problem.

Basically you’re sharing a ArrayList or similar structure for the various threads without any control mechanism or synchronization, thus violating the consistency of your program.

There are several ways to solve this. I will quote two.

Manual synchronization

Sync threads relative to the shared list so only one thread can modify the object at a time.

Example using synchronized:

//recupere a lista
List<Tarefa> tarefas = getTarefas();
Tarefa t;
//a partir daqui, somente uma thread execute de cada vez
synchronized (tarefas) {
  //o método remove de uma lista retorna o elemento removido
  t = tarefas.remove(0);
}
//processa o elemento não compartilhado t fora do bloco sincronizado,
//caso contrário vai enfileirar cada elemento
scan(t)

Thread-safe structure

There are some Java objects that allow you to perform operations directly across multiple threads safely.

For example, the LinkedBlockingDeque with his method poll() can be used, so simply have your to-do list using this type of object and its threads like this:

//pega o primeiro item da lista, removendo-o
Tarefa t = getTarefas().poll();
//null significa que a lista estava fazia
if (t != null) {
    scan(t)
}

In addition, the method take() can be used if you want the thread to wait for the list to have some element. Instead of returning null if the list is empty as in poll(), the method take() blocks the thread and waits for some element to be added.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.