multithreading - Sorting files in threads in java -
i have program sort array of files via threads. here sort class:
import java.io.bufferedreader; import java.io.file; import java.io.filereader; import java.io.ioexception; import java.util.arraylist; import java.util.concurrent.callable; import java.util.concurrent.executionexception; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.future; import java.util.concurrent.timeunit; public class sort { /** * implement method. method should invoke 1 or more * threads read , sort data collection of files. * method should return sorted list of of string data contained in * files. * * @param files * @return * @throws ioexception */ public static string[] threadedsort(file[] files) throws ioexception { executorservice executor = executors.newfixedthreadpool(files.length); future<string[]> value = null; string[] sorteddata = null; try { (int i=0; i<files.length-1; i++) { final sortingthread worker = new sortingthread(files[i]); executor.submit(worker); value = executor.submit(new callable<string[]>() { @override public string[] call() { return worker.getsorteddata(); } }); sorteddata = value.get(); executor.shutdown(); executor.awaittermination(5, timeunit.seconds); } } catch (interruptedexception | executionexception e) { e.printstacktrace(); } (int = 0; < sorteddata.length-1; i++) { system.out.println(sorteddata[i]); } return sorteddata; } /** * given array of files, method return sorted list of * string data contained in each of files. * * @param files * files read * @return sorted data * @throws ioexception * thrown if errors occur reading file */ public static string[] sort(file[] files) throws ioexception { string[] sorteddata = new string[0]; (file file : files) { string[] data = getdata(file); data = mergesort.mergesort(data); sorteddata = mergesort.merge(sorteddata, data); } return sorteddata; } /** * method read in string data specified file , * return data array of string objects. * * @param file * file containing string data * @return string array containing string data * @throws ioexception * thrown if errors occur reading file */ private static string[] getdata(file file) throws ioexception { arraylist<string> data = new arraylist<string>(); bufferedreader in = new bufferedreader(new filereader(file)); // read data file until end of file reached while (true) { string line = in.readline(); if (line == null) { // end of file reached break; } else { data.add(line); } } // close input stream , return data in.close(); return data.toarray(new string[0]); } static class sortingthread implements runnable { private file file; private string[] sorteddata = new string[0]; public sortingthread(file file) { this.file = file; } public string[] getsorteddata() { return sorteddata; } @override public void run() { try { string[] data = getdata(file); data = mergesort.mergesort(data); sorteddata = mergesort.merge(sorteddata, data); } catch (ioexception e) { e.printstacktrace(); } } } }
here merge sort class:
public class mergesort { // mergesort method returns sorted copy of // string objects contained in string array data. /** * sorts string objects using merge sort algorithm. * * @param data string objects sorted * @return string objects sorted in ascending order */ public static string[] mergesort(string[] data) { if (data.length > 1) { string[] left = new string[data.length / 2]; string[] right = new string[data.length - left.length]; system.arraycopy(data, 0, left, 0, left.length); system.arraycopy(data, left.length, right, 0, right.length); left = mergesort(left); right = mergesort(right); return merge(left, right); } else { return data; } } /** * merge method accepts 2 string arrays assumed * sorted in ascending order. method return * sorted array of string objects containing string objects * 2 input collections. * * @param left sorted collection of string objects * @param right sorted collection of string objects * @return sorted collection of string objects */ public static string[] merge(string[] left, string[] right) { string[] data = new string[left.length + right.length]; int lindex = 0; int rindex = 0; (int i=0; i<data.length; i++) { if (lindex == left.length) { data[i] = right[rindex]; rindex++; } else if (rindex == right.length) { data[i] = left[lindex]; lindex++; } else if (left[lindex].compareto(right[rindex]) < 0) { data[i] = left[lindex]; lindex++; } else { data[i] = right[rindex]; rindex++; } } return data; } }
and here test class:
import java.io.file; import java.io.ioexception; /** * class sorttest used test threaded , non-threaded sort * methods. program call each method sort data contained in * 4 test files. program test results ensure * results sorted in ascending order. * * run program verify have correctly implemented * threaded sort method. program not verify if sort uses threads, * verify if implementation correctly sorted data contained in * 4 files. * * there should no reason make modifications class. */ public class sorttest { public static void main(string[] args) throws ioexception, illegalstateexception { file[] files = { new file("res/file1.txt"), new file("res/file2.txt") }; // run sort.sort on files long starttime = system.nanotime(); string[] sorteddata = sort.sort(files); long stoptime = system.nanotime(); double elapsedtime = (stoptime - starttime) / 1000000000.0; // test ensure data sorted (int = 0; < sorteddata.length - 1; i++) { if (sorteddata[i].compareto(sorteddata[i + 1]) > 0) { system.out .println("the data returned sort.sort not sorted."); throw new java.lang.illegalstateexception( "the data returned sort.sort not sorted"); } } system.out.println("the data returned sort.sort sorted."); system.out.println("sort.sort took " + elapsedtime + " seconds read , sort data."); // run sort.threadedsort on files , test ensure data // sorted starttime = system.nanotime(); string[] threadsorteddata = sort.threadedsort(files); stoptime = system.nanotime(); double threadedelapsedtime = (stoptime - starttime) / 1000000000.0; // test ensure data sorted if (sorteddata.length != threadsorteddata.length) { system.out .println("the data return sort.threadedsort missing data"); throw new java.lang.illegalstateexception( "the data returned sort.threadedsort not sorted"); } (int = 0; < threadsorteddata.length - 1; i++) { if (threadsorteddata[i].compareto(threadsorteddata[i + 1]) > 0) { system.out .println("the data return sort.threadedsort not sorted"); throw new java.lang.illegalstateexception( "the data returned sort.threadedsort not sorted"); } } system.out.println("the data returned sort.threadedsort sorted."); system.out.println("sort.threadedsort took " + threadedelapsedtime + " seconds read , sort data."); } }
i have implemented threadedsort method using executor services don't know why i'm geting exception:
the data returned sort.sort sorted. sort.sort took 0.003480673 seconds read , sort data. data return sort.threadedsort missing data exception in thread "main" java.lang.illegalstateexception: data returned sort.threadedsort not sorted @ com.teamincredibles.threading.sorttest.main(sorttest.java:56)
i can't figure out i've done wrong please review. appriciated. thanks
you expecting result thread sortingthread
should use callable
, not runnable
as:
static class sortingthread implements callable<string[]> { private file file; private string[] sorteddata = new string[0]; public sortingthread(file file) { this.file = file; } public string[] getsorteddata() { return sorteddata; } @override public string[] call() throws exception { string[] data = getdata(file); data = mergesort.mergesort(data); sorteddata = mergesort.merge(sorteddata, data); return sorteddata; } }
now can create tasks submit executorservice
, future<string[]>
result.
public static string[] threadedsort(file[] files) throws ioexception, interruptedexception, executionexception { executorservice executor = executors.newfixedthreadpool(files.length); list<future<string[]>> futurelist = new arraylist<>(); string[] sorteddata = null; (int i=0; i<files.length; i++) { futurelist.add(executor.submit(new sortingthread(files[i]))); } executor.shutdown(); executor.awaittermination(1, timeunit.days); (future<string[]> future :futurelist) { string[] values = future.get(); // merge values , finaldata create 1 array. } return finaldata; }
also 5s
small time imo. can provide time of 1 day , if finishes before result else throw timeout exception.
i have suggested changes can @ least provide right direction. can further explore various ways improve code. example merging 2 arrays may expensive , can think better option.
Comments
Post a Comment