Repository navigation
Expand file tree
/
Copy pathCountWordMultiThread.java
More file actions
176 lines (146 loc) · 5.13 KB
/
Copy pathCountWordMultiThread.java
File metadata and controls
176 lines (146 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package com.github;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Reads a file from the command line parameter and counts the number of words in it
* @author gunjan
*/
public class CountWordMultiThread{
private static final int THREAD_COUNT = 4;
private static class FileIterator implements Iterator<String>, AutoCloseable
{
private final BufferedReader br;
private String nextLine;
public FileIterator( String fileName ) throws IOException
{
br = new BufferedReader( new FileReader( fileName ) );
nextLine = br.readLine();
}
@Override public boolean hasNext()
{
return nextLine != null;
}
@Override public String next()
{
String lineToReturn = nextLine;
try {
nextLine = br.readLine();
} catch ( IOException e ) {
nextLine = null;
}
return lineToReturn;
}
@Override public void remove()
{
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override public void close() throws IOException
{
br.close();
}
}
private static class Transformers
{
public String[] mapToTokens( String input )
{
return input.split( "[ _\\-\\,.\\+]" );
}
private String[] filterIllegalTokens( String[] words )
{
List<String> filteredList = new ArrayList<>();
for ( String word : words ) {
if ( word.matches( "[a-zA-Z]+" ) ) {
filteredList.add( word );
}
}
return filteredList.toArray( new String[filteredList.size()] );
}
private String[] mapToUpperCase( String[] words )
{
String[] filteredList = new String[words.length];
for ( int i = 0; i < words.length; i++ ) {
filteredList[i] = words[i].toUpperCase();
}
return filteredList;
}
public synchronized void reduce( Map<String, Integer> counter, String word )
{
if ( counter.containsKey( word ) ) {
counter.put( word, counter.get( word ) + 1 );
} else {
counter.put( word, 1 );
}
}
}
private static class TransformationThread implements Runnable
{
private Transformers tr;
private Queue<String> dataQueue;
private Map<String, Integer> counters;
public TransformationThread( Transformers tr, Map<String, Integer> counters, Queue<String> dataQueue )
{
this.tr = tr;
this.dataQueue = dataQueue;
this.counters = counters;
}
@Override public void run()
{
while ( !dataQueue.isEmpty() ) {
String line = dataQueue.poll();
if ( line != null ) {
String[] words = tr.mapToTokens( line );
String[] legalWords = tr.filterIllegalTokens( words );
String[] lowerCaseWords = tr.mapToUpperCase( legalWords );
for ( String word : lowerCaseWords ) {
tr.reduce( counters, word );
}
}
}
}
}
public static void main( final String[] args ) throws Exception
{
Transformers tr = new Transformers();
Map<String, Integer> counters = new HashMap<>();
final Queue<String> q = new ConcurrentLinkedQueue<>();
new Thread()
{
@Override public void run()
{
try ( FileIterator fc = new FileIterator( args[0] ) ) {
while ( fc.hasNext() ) {
q.add( fc.next() );
}
} catch ( IOException e ) {
e.printStackTrace();
}
}
}.start();
while ( q.isEmpty() ) {
// Wait for the thread to start writing into the queue
Thread.sleep( 10 );
}
ExecutorService es = Executors.newFixedThreadPool( THREAD_COUNT );
for ( int i = 0; i < THREAD_COUNT; i++ ) {
es.execute( new TransformationThread( tr, counters, q ) );
}
es.shutdown();
es.awaitTermination( 1, TimeUnit.MINUTES );
System.out.println( "Word Count:\n" + counters );
}
}