Синхронизированный метод () работает только 1 поток до конца из опроса нескольких - PullRequest
0 голосов
/ 03 мая 2018

Это проект, который я пытаюсь сделать для университета.

Я создаю приложение, используя сокеты для подключения нескольких Клиентов к Серверу. Когда я получаю новое соединение, вызывается новый экземпляр ServerHandler, который прослушивает порт для запросов от клиента.

Это мой класс ServerHandler

public class ServerHandler implements Runnable {

    private Socket clientSocket;
    private Server server;
    ArrayList<Thread> threads = new ArrayList<Thread>();
    ArrayList<News> news = new ArrayList<News>();
    ArrayList<News> filteredNews = new ArrayList<>();
    private int iterator = 0;
    private boolean available = true;
    private boolean finished = false;

    public ServerHandler(Socket clientSocket, Server server) {
        this.clientSocket = clientSocket;
        this.server = server;
        this.news = server.getListNews();
    }

    @Override
    public void run() {
        System.out.println("Hello!");
        while(true) {
            try {
                System.out.println("Waiting for input");
                BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                String str = br.readLine();
                System.out.println(str);
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            manageMessages();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }                       
                    }

                    private void manageMessages() throws IOException, InterruptedException {
                        System.out.println("Button Search.");
                        launchThreads(str);
                        for(Thread t : threads) {
                            t.join();
                        }
                        filteredNews.sort(null);
                        System.out.println("News have been filtered and sorted.");
                        System.out.println("Sending info to Client.");
                        sendtoClient();
                        System.out.println("Sent info to Client.");             
                    }
                }).start();

            } catch (IOException e) {
                System.out.println("Socket closed" + e);
                break;
            }
        }

    }

Когда я получаю запрос, я запускаю новый поток, отвечающий за возвращение чего-либо клиенту.

Моя проблема связана с методом launchThreads(String str). Этот метод предназначен для создания и добавления 10 потоков в массив потоков. Затем каждый поток будет проходить через те же ArrayList новостей в поисках слова (String str, отправленного клиентом).

Все темы должны делиться работой, которая ищет String str в каждой новости в общем ArrayList<News>.

private void launchThreads(String str) {
    System.out.println("Lauching threads");
    filteredNews.clear();
    threads.clear();
    finished = false;
    available = true;
    iterator = 0;
    for(int i = 0; i < 10; i++) {
        threads.add(new Thread(new Runnable(){public void run(){try {
            queueThreads(str);
            filterNews(str);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }}}));
        threads.get(i).start();
    }
    System.out.println("Launched threads: " + threads.size());
}

private synchronized void queueThreads(String str) throws InterruptedException {
    while(!available && !finished) {
        System.out.println("Waiting.");
        wait();
    }
    System.out.println("Gone through.");
    available = false;  
}

private synchronized void filterNews(String str) throws InterruptedException {
    int contador = 0;
    if(iterator < news.size()) {
        String temp = news.get(iterator).getTitle() + " " + news.get(iterator).getBody();
        String[] tempArray = temp.replaceAll("[^a-zA-Z ]", "").split("\\s+");
        for(String word : tempArray) {
            if(word.equalsIgnoreCase(str)) {
                contador++;
            }
        }
        if(contador > 0) {
            News n = new News(news.get(iterator).getTitle(),news.get(iterator).getBody(), contador);
            n.setTitle(contador + " - " + n.getTitle());
            System.out.println(news.get(iterator).toString());
            filteredNews.add(n);
        }
        iterator++;
    }else {
        finished = true;
    }
    available = true;
    notifyAll();
    queueThreads(str);}

Я получаю только то, что только 1 поток выполняет весь поиск, тогда как остальные просто ждут, пока я не изменю флаг завершения на 'true', который устанавливается после окончания поиска.

Я бы хотел получить некоторую помощь о том, как я могу запустить несколько потоков, чтобы выполнить работу по распределению массивов между ними.

Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...