Java: поток, передающий параметры другому потоку - PullRequest
3 голосов
/ 19 марта 2012

У меня есть два Java-класса, которые называются Reader и Worker.Reader читает строки из текстового файла и передает эти строки рабочим, которые сортируют эти строки в дерево.Поэтому я создаю несколько рабочих потоков и 1 поток Reader:

        try {      

        /* Create and run worker processes. */
        workers = new TrieWorker[numberOfWorkers];
        for(int i = 0; i < numberOfWorkers; i++)
        {
            workers[i] = new TrieWorker(this);
            new Thread(workers[i]).run();
        }

        /* Create and run reader process. */
        reader  = new TrieReader(this, filename);                        
        new Thread(reader).run();

    } catch(Exception e) {
        e.printStackTrace();
    }

Когда мой Reader читает строку из текстового файла внутри метода run (), он передает эту строку одному из работниковвызывая

workers[i].add(string);

Рабочие в основном ничего не делают, пока этот метод не был вызван.Поэтому мне интересно, продолжает ли Reader читать текстовый файл сразу после того, как он передает этот параметр одному из рабочих?Или он возвращается из этого метода только после того, как Worker завершил работу со строкой?Другими словами, когда один Поток передает параметры другому, они оба продолжают делать свое дело, если только Поток, передающий параметры, не хочет получить какой-то ответ?

Надеюсь, вы, ребята, понимаете, что я имею в виду, очень сложнообъяснить.

РЕДАКТИРОВАТЬ: Спасибо за хорошие ответы!Вот код класса Reader:

private static int numberOfNextWorker = 0;

    public void run() 
{
    System.out.println("Reader run.");

    try {
        System.out.println("Reading " + filename);
        read();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void read() throws Exception
{
    File file = new File(filename);
    Scanner reader = new Scanner(file);

    if(file.canRead() == false)
        throw new Exception("file " + filename + " cannot be read.");

    long totalLength = file.length();

    while(reader.hasNextLine())
    {

            String text = reader.nextLine();          
            numberOfLines++;

            /* Passes the work on to workers. */
            if(numberOfNextWorker == (numberOfWorkers - 1))
                 numberOfNextWorker = 0;
            else
                 numberOfNextWorker++;

            workers[numberOfNextWorker].add(text); 
        }
}

А вот работник:

    public void run() 
{
    System.out.println("Worker run.");
}

void add(String text) 
{
    numberOfStrings++;
    char[] chars = text.toCharArray();

    int i = 0;
    Node node = new Node();

    while (chars.length > i) {
        node.value = chars[i];
        node = node.children;
        i++;
    }
}

Пока что он не делает ничего мудрого :) Думаю, я понял, что вы сказали.Я много читал эту книгу о параллелизме и выполнял некоторые упражнения на бумаге, но не пытался что-либо особо кодировать.

Ответы [ 3 ]

6 голосов
/ 19 марта 2012

Обратите внимание, что вы не запускаете новый поток в любой точке, а только вызываете метод run () в том же потоке.

Вам необходимо вызвать start(), чтобы создать новый поток, дляпример:

new Thread(workers[i]).start();

вместо

new Thread(workers[i]).run();

Как конкретно потоки будут продолжать работать, зависит от вашей реализации.

2 голосов
/ 19 марта 2012

Вызов Worker.add блокируется, поэтому он ожидает, пока add () не будет завершено.Все это выполняется в потоке 1. Если Worker.add должен просто добавить работу в список работ, а в методе run () обработать свою работу (выполненную в своем собственном потоке).

Этоклассическая проблема потребителей / производителей.(Блокировка). Очереди могут вам помочь.

1 голос
/ 19 марта 2012

Вам нужен третий класс, называемый ресурсом. Ваши темы будут общаться через общий ресурс. Подумайте производитель-потребитель Ваши работники добавят в sortedReult.

public class Resource{
  Queue<String> semaphore = new LinkedList<String>();
  Queue<String> sortedResult = new LinkedList<String>();

  public synchronized addStrings(List<String> words){//for reader
    semaphore.addAll(words);
    notify();
  }//

  public synchronized String getString(){//for workers
    while(semaphore.isEmpty())
       try{ wait();}
       catch(InterruptedException e){}
    return semaphore.remove();
  }
}

Кстати, то, что вы вызываете run (), показывает, что вы понимаете логику. Но в Java вы должны вызвать start () и позволить start (), в свою очередь, вызвать run () для вас.

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