Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You are on the right track using <code>Runnable</code>. You have a couple problems right now:</p> <ol> <li>You currently create 1 <code>fileReader</code> with 1 thread for both files, but your intent is to have a <em>separate</em> thread for each.</li> <li>You are trying to communicate between threads using some static variables, but you're not waiting for the worker thread to be done before printing the variables.</li> </ol> <p>To solve your first problem, you need to create a new <code>Runnable</code> and a new thread for each file. (I'm going to rename your <code>fileReader</code> class to <code>LineCounter</code> to avoid confusion with the similarly named <code>FileReader</code> from the standard library).</p> <pre><code>class LineCounter implements Runnable { private final File file; public LineCounter(File file) { this.file = file; } public void run() { // Count lines in file. } } </code></pre> <p>Now you can create 2 separate LineCounter objects, one to count the lines in each file.</p> <pre><code>Thread thread1 = new Thread(new LineCounter(new File("filetest1.txt"))); Thread thread2 = new Thread(new LineCounter(new File("filetest2.txt"))); thread1.start(); thread2.start(); </code></pre> <p>As for your second problem, your main thread must (the one that spawned off these two other threads) needs to wait for them to complete before reading the variables holding the number of lines in each file. You can instruct your main thread to wait for the another thread to complete by using <code>join()</code></p> <pre><code>thread1.join(); thread2.join(); // Print your variables. </code></pre> <p>That being said, communicating between threads with static variables is dubious at best:</p> <ol> <li>To really do this right, you'd have to either <code>synchronize</code> access to those variables, or else declare them as <code>volatile</code>.</li> <li>When programming with threads, it's preferable to share as little state (variables) as possible with other threads.</li> </ol> <p>Further, there exists the very convenient <code>Executor</code> framework which presents a nicer API for dealing with threads. One big win is that is allows you to easily return a value from a thread, which you could use to return the number of lines read.</p> <p>The big changes are:</p> <ul> <li>Your class implements <code>Callable&lt;Integer&gt;</code> instead of <code>Runnable</code>. The <code>&lt;Integer&gt;</code> part here means you want your thread to return an Integer (i.e. the number of lines in the file)</li> <li>Instead of <code>void run()</code>, you define <code>Integer call()</code>, which returns the number of lines in the file.</li> <li>Instead of creating <code>Thread</code>s directly, you <em>submit</em> tasks to be done to an <code>Executor</code>.</li> <li>Instead of <code>join()</code>ing threads together, simply <code>get()</code> the return value of a thread from a <code>Future</code>.</li> </ul> <p>Converted to Executor style, the solution is something like</p> <pre><code>class LineCounter implements Callable&lt;Integer&gt; { private final File file; public LineCounter(File file) { this.file = file; } public Integer call() { // Count number of lines in file. return numLines; } } </code></pre> <p>And in your main thread:</p> <pre><code>ExecutorService executor = Executors.newFixedThreadPool(2); Future&lt;Integer&gt; future1 = executor.submit(new LineCounter(new File("file1.txt"))); Future&lt;Integer&gt; future2 = executor.submit(new LineCounter(new File("file2.txt"))); Integer file1Lines = future1.get(); Integer file2Lines = future2.get(); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload