Method cannot get updated value from a varible - java

I am trying to count number of words from three text files respectively. Three classes are running in multi-threads. In each thread, sum of the counted words will be passed to a class counter and update to sum all counts to the counter after all threads are completed.
I meet two problem that the "totalWordCount" can be updated by the class setter. But it cannot be gotten by a getter in the same class. Other problem is that I cannot check the Readfiles threads alive.
I have searched on internet & shoot many times but cannot solve, any comment are welcome, thanks a lot!
NumberWords class:
public class NumberWords {
private int activeThread;
private int totalWordCount;
private String getThreadName;
public NumberWords(int activeThread) {
this.activeThread = activeThread;
}
public synchronized void incTotalWordCount(int n) {
totalWordCount += n;
System.out.println("The total word count is " + totalWordCount);
}
public synchronized void printCount() {
System.out.println("The total word count(print count) is " + totalWordCount);
}
public synchronized void decActiveThread() {
getThreadName = Thread.currentThread().getName();
System.out.println(getThreadName);
if (Thread.getAllStackTraces().keySet().size() != 0) {
// Get number of active threads
activeThread = Thread.getAllStackTraces().keySet().size();
activeThread--;
if (activeThread == 0) {
System.out.println("The total number of word in the three files is " + totalWordCount);
System.out.println("The active threads is/are " + activeThread);
}
}
}
}
Read file and count number of words:
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
public class ReadFile1 extends Thread implements Runnable {
private NumberWords nw;
public ReadFile1(NumberWords nw) {
this.nw = nw;
}
//set file path
String path1 = System.getProperty("user.dir") + File.separator + "text1.txt";
BufferedReader br1 = null;
public void run() {
try {
br1 = new BufferedReader(new FileReader(path1));
String contentLine = br1.readLine();
while (contentLine != null) {
// Count number of words
String[] parts = contentLine.split(" ");
int count = 0;
for (int i = 0; i < parts.length; i++) {
count++;
}
// Check number of words counted.
System.out.println("The number of words in file(text1.txt) is " + count);
//Pass words count to sum
nw.incTotalWordCount(count);
contentLine = br1.readLine();
}
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (br1 != null) {
br1.close();
}
} catch (IOException ioe) {
System.out.println("Error in closing the BufferedReader");
}
}
}
}
Main class:
public class TestReadFile {
public static void main(String args[]){
NumberWords nw = new NumberWords(args.length);
Thread rf1 = new Thread(new ReadFile1(nw));
Thread rf2 = new Thread(new ReadFile2(nw));
Thread rf3 = new Thread(new ReadFile3(nw));
rf1.start();
rf2.start();
rf3.start();
//Get total word cont
nw.decActiveThread();
}
}

How about this:
public class NumberWords {
private int totalWordCount;
private int activeThreads;
public synchronized void incTotalWordCount(int n) {
totalWordCount += n;
activeThreads--;
System.out.println("The total word count is " + totalWordCount);
}
public synchronized void printCount() {
System.out.println("The total word count(print count) is " + totalWordCount);
}
public int getActiveThreads() {
return activeThreads;
}
public void setActiveThreads(int activeThreads) {
this.activeThreads = activeThreads;
}
}
ReadFile:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ReadFile implements Runnable {
private NumberWords nw;
private Path filePath;
public ReadFile(NumberWords nw, Path filePath) {
this.nw = nw;
this.filePath = filePath;
}
BufferedReader br1 = null;
public void run() {
try {
int count = 0;
for (String line : Files.readAllLines(filePath)) {
String[] parts = line.split(" ");
for (String w : parts) {
count++;
}
}
nw.incTotalWordCount(count);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Main:
import java.io.File;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String args[]) throws InterruptedException {
NumberWords nw = new NumberWords();
ExecutorService execSvc = Executors.newCachedThreadPool();
new Thread(new ReadFile(nw, Paths.get(System.getProperty("user.dir") + File.separator + "text1.txt"))).start();
new Thread(new ReadFile(nw, Paths.get(System.getProperty("user.dir") + File.separator + "text2.txt"))).start();
new Thread(new ReadFile(nw, Paths.get(System.getProperty("user.dir") + File.separator + "text3.txt"))).start();
nw.setActiveThreads(3);
while (nw.getActiveThreads() > 0) {
Thread.sleep(100);
System.out.println("Waiting for Tasks to complete!");
}
nw.printCount();
}
}

Related

Sequential writing and reading (two threads)

The topic was continued here:
https://codereview.stackexchange.com/q/249978/231182
I am new to the Java programming language.
Task: Create SequentalWriter and SequentalReader classes that implement the Runnable interface. They must provide a sequence of write-read operations (i.e., write-read-write-read-write-read, etc.).
I would like to know if this implementation is correct or something needs to be changed?
Besides, minor bugs and errors are also welcome.
import java.lang.Thread;
import vectors.Array; /* My array implementation */
import vectors.CircularLinkedList; /* My list implementation */
import vectors.IVector; /* The interface that Array and CircularLinkedList implement */
public class Task7Part2 {
volatile int a = 0;
public static void main(String[] args) {
IVector arr1 = new Array(2);
System.out.print("[Test] arr1: "); arr1.print();
Keeper keeperArr1 = new Keeper(arr1);
SequentalWriter seqWriter = new SequentalWriter(keeperArr1);
SequentalReader seqReader = new SequentalReader(keeperArr1);
(new Thread(seqWriter)).start();
(new Thread(seqReader)).start();
// Задержка
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
IVector arr2 = new Array(3);
System.out.print("[Test] arr2: "); arr2.print();
Keeper keeperArr2 = new Keeper(arr2);
seqWriter = new SequentalWriter(keeperArr2);
seqReader = new SequentalReader(keeperArr2);
(new Thread(seqWriter)).start();
(new Thread(seqReader)).start();
// Задержка
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
IVector list = new CircularLinkedList(4);
System.out.print("[Test] list: "); list.print();
Keeper keeperList = new Keeper(list);
seqWriter = new SequentalWriter(keeperList);
seqReader = new SequentalReader(keeperList);
(new Thread(seqWriter)).start();
(new Thread(seqReader)).start();
}
public static class Keeper {
public volatile IVector vector;
public volatile boolean isWrite;
public Keeper(IVector vector) {
this.vector = vector;
this.isWrite = true;
}
}
public static class SequentalWriter implements Runnable {
public SequentalWriter(Keeper keeper) {
this.keeper = keeper;
}
public void run() {
try {
for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
double d = Math.random();
synchronized(keeper) {
while (!keeper.isWrite) {
keeper.wait();
}
keeper.vector.set(i, d);
System.out.println("Write: " + d + " to position " + i);
keeper.isWrite = false;
keeper.notify();
}
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
private Keeper keeper;
}
public static class SequentalReader implements Runnable {
public SequentalReader(Keeper keeper) {
this.keeper = keeper;
}
public void run() {
try {
for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
synchronized(keeper) {
while (keeper.isWrite) {
keeper.wait();
}
System.out.println("Read: " + keeper.vector.get(i) + " from position " + i);
keeper.isWrite = true;
keeper.notify();
}
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
private Keeper keeper;
}
}
Expected behavior (What seems to work right now, but I'm not sure it will always be that way.):
[Test] arr1: 0.0 0.0
Write: 0.11832270210075957 to position 0
Read: 0.11832270210075957 from position 0
Write: 0.18019604451043925 to position 1
Read: 0.18019604451043925 from position 1
[Test] arr2: 0.0 0.0 0.0
Write: 0.9208224707735939 to position 0
Read: 0.9208224707735939 from position 0
Write: 0.5204299894796229 to position 1
Read: 0.5204299894796229 from position 1
Write: 0.6221915557485913 to position 2
Read: 0.6221915557485913 from position 2
[Test] list: 0.0 0.0 0.0 0.0
Write: 0.2718292615666258 to position 0
Read: 0.2718292615666258 from position 0
Write: 0.5589338156490498 to position 1
Read: 0.5589338156490498 from position 1
Write: 0.11919746734454817 to position 2
Read: 0.11919746734454817 from position 2
Write: 0.7266106446478366 to position 3
Read: 0.7266106446478366 from position 3
the classic approach is to use Semaphores:
import java.lang.Thread;
import java.util.concurrent.Semaphore;
public class Task7Part2 {
public static void main(String[] args) throws InterruptedException {
IVector arr1 = new IVector(2);
System.out.print("[Test] arr1: "); arr1.print();
Keeper keeperArr1 = new Keeper(arr1);
SequentalWriter seqWriter = new SequentalWriter(keeperArr1);
SequentalReader seqReader = new SequentalReader(keeperArr1);
Thread thread1 = new Thread(seqWriter);
thread1.start();
Thread thread2 = new Thread(seqReader);
thread2.start();
thread1.join();
thread2.join();
}
public static class Keeper {
public IVector vector;
public Semaphore allowWrite=new Semaphore(1);
public Semaphore allowRead=new Semaphore(0);
public Keeper(IVector vector) {
this.vector = vector;
}
public Double get(int i) throws InterruptedException {
allowRead.acquire();
Double res = vector.get(i);
allowWrite.release();
return res;
}
public void set(int i, double d) throws InterruptedException {
allowWrite.acquire();
vector.set(i,d);
allowRead.release();
}
}
public static class SequentalWriter implements Runnable {
private Keeper keeper;
public SequentalWriter(Keeper keeper) {
this.keeper = keeper;
}
public void run() {
try {
for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
double d = Math.random();
keeper.set(i, d);
System.out.println("Write: " + d + " to position " + i);
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
public static class SequentalReader implements Runnable {
private Keeper keeper;
public SequentalReader(Keeper keeper) {
this.keeper = keeper;
}
public void run() {
try {
for (int i = 0, size = keeper.vector.size(); i < size; ++i) {
System.out.println("Read: " + keeper.get(i) + " from position " + i);
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
}

How to close one window using Control D/Z without exiting the whole program (multithreaded java socket)

Screenshot of program running (top left: server, the rest are clients):
In the bottom-right window, I am trying to press Control D (mac) (for windows it's control Z) in order to exit the bottom right window/client alone without exiting the entire application/program but it doesn't seem to be working because I can still type "it didn't work" and it outputs the message.
My question is: What changes can I make to the following code so that when a client presses Control D it will close just one window/client and not exit the whole application?
Part of code that should close the window (currently empty):
//This is the code that prints messages to all clients
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (!line.equals(null) && !line.equals("null") && !line.equals(null) && !line.equals("F") && !line.equals("m") && !line.equals("M") && threads[i] != null && threads[i].clientName != null && !threads[i].clientName.equals("m") && !threads[i].clientName.equals("M"))
{
if(!line.equals("") == true && line.isEmpty()== false)
{
threads[i].os.println(name + ": " + line);
}
}
//After Control D/Z is pressed, this code will execute
else if(line.equals(null) || line.equals("null") || line.contains("null"))
{
try
{
//This code location exits the program, system.exit(0) and system.exit(-1) didn't work
//how do i close only one client window here without exiting the whole program?
}
catch (NullPointerException ignored)
{
}
finally
{
}
// threads[i].os.close();
// System.exit(0);
}
}
}
NOTE: SKIP THE REST and scroll down if you already know the answer
Full code of ClientThreads.java:
import java.io.*;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.nio.*;
import java.nio.channels.FileChannel;
class ClientThreads extends Thread
{
public String path = "";
public String name1 = "";
private String clientName = null;
private DataInputStream is = null;
private PrintStream os = null;
private Socket clientSocket = null;
private final ClientThreads[] threads;
private int maxClientsCount;
public int position = 0;
public static List<String> listName = Collections.synchronizedList(new ArrayList<String>());
List<String> l = Collections.synchronizedList(new ArrayList<String>());
public String[] namesList = new String[10];
public ClientThreads(Socket clientSocket, ClientThreads[] threads,
String name, String[] namesList, List<String> listName)
{
this.clientSocket = clientSocket;
this.threads = threads;
maxClientsCount = threads.length;
this.name1 = name;
this.namesList = namesList;
}
#SuppressWarnings("deprecation")
public void run()
{
int maxClientsCount = this.maxClientsCount;
ClientThreads[] threads = this.threads;
synchronized (listName)
{
//Iterator i = listName.iterator(); // Must be in synchronized block
ListIterator<String> i = listName.listIterator();
}
try
{
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
String name;
String name3;
while (true)
{
//os.println("What is your name?");
name = is.readLine().trim();
name3 = name;
break;
}
synchronized(listName)
{
if(!listName.contains(name))
{
if(!listName.contains(name) && name != null && !name.isEmpty())
{
listName.add(name);
Path currentRelativePath = Paths.get("");
path = currentRelativePath.toAbsolutePath().toString();
}
}
}
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] != null && threads[i] == this)
{
clientName = "#" + name;
break;
}
}
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] != null)
{
}
}
}
while (true)
{
synchronized(listName)
{
}
String line = is.readLine();
if (line.contains("3582938758912781739713asfaiwef;owjouruuzlxjcjnbbiewruwoerpqKFDJiuxo9"))
{
break;
}
else
{
}
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (!line.equals(null) && !line.equals("null") && !line.equals(null) && !line.equals("F") && !line.equals("m") && !line.equals("M") && threads[i] != null && threads[i].clientName != null && !threads[i].clientName.equals("m") && !threads[i].clientName.equals("M"))
{
if(!line.equals("") == true && line.isEmpty()== false)
{
threads[i].os.println(name + ": " + line);
}
}
else if(line.equals(null) || line.equals("null") || line.contains("null"))
{
try
{
//This code location exits the program, system.exit(0) and system.exit(-1) didn't work
//how do i close only one client window here without exiting the whole program?
}
catch (NullPointerException ignored)
{
}
finally
{
}
// threads[i].os.close();
// System.exit(0);
}
}
}
// }
}
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] != null && threads[i] != this && threads[i].clientName != null)
{
// threads[i].os.println(name + "has disconnected.");
threads[i].listName.remove(name);
listName.remove(name);
// threads[i].os.println("The list now contains: " + listName);
// System.out.println("A user disconnected. The list now contains: " +listName);
}
}
}
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] == this)
{
//threads[i] = null;
}
}
}
// is.close();
// os.close();
//clientSocket.close();
}
catch (IOException e)
{
}
}
}
Full code of ChatClient.java:
import java.io.*;
import java.net.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ChatClient implements Runnable
{
public static String path = "";
private static Socket clientSocket = null;
private static PrintStream os = null;
private static DataInputStream is = null;
private static BufferedReader inputLine = null;
private static boolean closed = false;
public static String[] namesList = new String[10];
public int iteration = 0;
public static String[] responses = new String[50];
public int responseCount = 0;
public static final int maxClientsCount = 10;
public static final ClientThreads[] threads = new ClientThreads[maxClientsCount];
public static List<String> listName = Collections.synchronizedList(new ArrayList<String>());
List<String> l = Collections.synchronizedList(new ArrayList<String>());
public ChatClient()
{
}
public static void main(String[] args)
{
for(int i = 0; i < namesList.length; i++)
{
namesList[i] = "";
}
for(int j = 0; j < responses.length; j++)
{
responses[j] = "";
}
// System.out.println("args[0] is: " + args[0]);
int portNumber = Integer.valueOf(args[0]);
String host = "localhost";
//int filePort = Integer.valueOf(args[0]);
try
{
synchronized(listName)
{
clientSocket = new Socket(host, portNumber);
inputLine = new BufferedReader(new InputStreamReader(System.in));
os = new PrintStream(clientSocket.getOutputStream());
is = new DataInputStream(clientSocket.getInputStream());
}
}
catch (UnknownHostException e)
{
//System.err.println("Don't know about host " + host);
} catch (IOException e)
{
// System.err.println("Couldn't get I/O for the connection to the host "
// + host);
}
if (clientSocket != null && os != null && is != null)
{
try
{
new Thread(new ChatClient()).start();
while (!closed)
{
os.println(inputLine.readLine() );
}
// os.close();
//is.close();
//clientSocket.close();
}
catch (IOException e)
{
// System.err.println("IOException: " + e);
}
}
}
#SuppressWarnings("deprecation")
public void run()
{
String responseLine = "";
try
{
while ((responseLine = is.readLine()) != null)
{
if(responseLine!=null && !responseLine.equals(null) && responseLine!="null" && !responseLine.equals("null") && !responseLine.contains("null"))
{
System.out.println(responseLine);
}
else if(responseLine.contains("null") || responseLine.equals("null") || responseLine==null || responseLine.equals(null))
{
//This is another location which will be executed if Control D/Control Z is pressed
//os.close();
// is.close();
//System.exit(0);
}
}
//closed = true;
}
catch (IOException e)
{
// System.err.println("IOException: " + e);
}
}
}
Full code of ChatServer.java:
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer
{
public static List<String> listName = Collections.synchronizedList(new ArrayList<String>());
List<String> l = Collections.synchronizedList(new ArrayList<String>());
public static ServerSocket serverSocket = null;
public static Socket clientSocket = null;
public static final int maxClientsCount = 10;
public static final ClientThreads[] threads = new ClientThreads[maxClientsCount];
public static String[] namesList = new String[10];
// public ChatClient arrayOfNames = new ChatClient;
public static void main(String args[])
{
synchronized (listName)
{
//Iterator i = listName.iterator(); // Must be in synchronized block
Iterator<String> i = listName.listIterator();
}
int once = 0;
if(once == 0)
{
// System.out.println("args[0] is: " + args[0]);
int portNumber = Integer.valueOf(args[0]);
// System.out.println("waiting for connections on port " + portNumber + " ...\n ");
once = 3;
}
once = 3;
try
{
int portNumber1 = Integer.valueOf(args[0]);
serverSocket = new ServerSocket(portNumber1);
}
catch (IOException e)
{
System.out.println(e);
}
while (true)
{
try
{
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++)
{
if (threads[i] == null)
{
String name = "";
(threads[i] = new ClientThreads(clientSocket, threads, name, namesList, listName)).start();
break;
}
}
if (i == maxClientsCount)
{
//PrintStream os = new PrintStream(clientSocket.getOutputStream());
// os.println("Server too busy. Try later.");
// os.close();
// clientSocket.close();
}
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
EDIT: it might also be possible to change threads[i] to threads[i+1] in order to keep track of different clients in certain parts of the code
What you need instead of this:
while (!closed)
{
os.println(inputLine.readLine() );
}
is this:
String line;
while ((line = inputLine.readLine()) != null)
{
os.println(line);
}
This will fall-through when ctrl/d or ctrl/z is pressed, as appropriate, and main() will then exit. Provided you have also made your threads daemons, the JVM will then exit.
NB this:
// After Control D/Z is pressed, this code will execute
isn't true, and this:
else if(line.equals(null) || line.equals("null") || line.contains("null"))
is drivel. line.equals(null) can never be true, by definition, otherwise a NullPointerException would have been thrown instead of calling .equals(): and why you should be interested in whether the user has typed "null", or something containing "null", is a mystery.
And why you are using synchronized(listName) in the main() method of an application which up to this point is single-threaded is another mystery.

Can I combine this into one loop? [duplicate]

This question already has answers here:
How to chain multiple different InputStreams into one InputStream
(5 answers)
Closed 8 years ago.
Hi i have a run method thats inside a Thread that writes either using a fileOutputStream stream or a RandomaccessFile. I have it in 2 while loops I'de like to combine it into 1 but I'm lost as to how. here is the run method.
package treadmakestop;
import java.awt.EventQueue;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
/**
*
* #author brett
*/
public class Worker implements Runnable {
private final ReentrantLock PAUSELOCK;
private final Condition PAUSECONDITION;
private final AtomicBoolean PAUSED;
private final AtomicBoolean KEEPRUNNING;
private final AtomicBoolean KILLSTREAM;
private final File FILEIN = new File("C:\\Users\\brett\\Documents\\Back to the Beginning Origins Nova Neil Degrasse Tyson Documentary-D-EXw5CdPtM.mp4");
private final File WORKINGDIR = new File(System.getProperty("user.home") + File.separator + "Documents" + File.separator + "ConvertedTvFiles" + File.separator);
private final File FILEOUT = new File(WORKINGDIR + File.separator + "spew" + ".mp4");
private final JProgressBar TVPG;
private final long LENGTH = FILEIN.length();
private final byte[] b = new byte[1024];
private FileOutputStream FOUTS;
private FileInputStream FINS;
private RandomAccessFile RandFileOut;
private RandomAccessFile RandFileIn;
private int r;
private long Counter = 1;
public Worker(JProgressBar tvpg) {
PAUSED = new AtomicBoolean();
KEEPRUNNING = new AtomicBoolean(true);
KILLSTREAM = new AtomicBoolean(false);
PAUSELOCK = new ReentrantLock();
PAUSECONDITION = PAUSELOCK.newCondition();
TVPG = tvpg;
}
/**
* This is the main thread and copy file operation
*/
#Override
public void run() {
System.out.println("Runnable has started");
int progress;
try {
createFirstFileStream();
while ((r = FINS.read(b)) != -1 && KEEPRUNNING.get()) {
checkPauseState();
if (!KILLSTREAM.get()) {
Counter += r;
FOUTS.write(b, 0, r);
progress = (int) Math.round(100 * Counter / LENGTH);
updateProgress(Math.min(progress, 100));
} else {
killFileStream();
break;
}
}
createRandomFile();
while ((r = RandFileIn.read(b)) != -1 && KEEPRUNNING.get()) {
checkPauseState();
if (KILLSTREAM.get()) {
Counter += r;
RandFileOut.write(b, 0, r);
progress = (int) Math.round(100 * Counter / LENGTH);
updateProgress(Math.min(progress, 100));
} else {
killRandFile();
break;
}
}
} catch (IOException ex) {
Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Runnable has exited");
}
public void createFirstFileStream() throws IOException {
FINS = new FileInputStream(FILEIN);
FOUTS = new FileOutputStream(FILEOUT);
}
public void createRandomFile() throws IOException {
RandFileIn = new RandomAccessFile(FILEIN, "rw");
RandFileIn.seek(FILEOUT.length());
long pointer = RandFileIn.getFilePointer();
RandFileOut = new RandomAccessFile(FILEOUT, "rw");
RandFileOut.seek(pointer);
}
public boolean isPaused() {
return PAUSED.get();
}
public void pause() {
KILLSTREAM.set(true);
PAUSED.set(true);
}
public void resume() {
PAUSED.set(false);
PAUSELOCK.lock();
try {
PAUSECONDITION.signal();
} finally {
PAUSELOCK.unlock();
}
}
protected void checkPauseState() {
while (PAUSED.get()) {
PAUSELOCK.lock();
try {
PAUSECONDITION.await();
} catch (Exception e) {
} finally {
PAUSELOCK.unlock();
}
}
}
protected void updateProgress(int progress) {
if (EventQueue.isDispatchThread()) {
TVPG.setValue(progress);
if (KEEPRUNNING.get() == false) {
TVPG.setValue(0);
}
} else {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
updateProgress(progress);
}
});
}
}
public void killFileStream() throws IOException {
FINS.close();
FOUTS.flush();
FOUTS.close();
}
public void killRandFile() throws IOException {
RandFileIn.close();
RandFileOut.close();
}
public synchronized void stop() {
KEEPRUNNING.set(false);
resume();
}
}
Here is the whole class
Something like this should work:
createFirstFileStream();
createRandomFile();
InputStream combined = new SequentialInputStream(FINS,
Channels.createInputStream(RandomFileIn.getChannel());
// your while loop
while ((r = combined.read(b)) != -1 && KEEPRUNNING.get()) {
if (!KILLSTREAM.get()) {
Counter += r;
FOUTS.write(b, 0, r);
progress = (int) Math.round(100 * Counter / LENGTH);
updateProgress(Math.min(progress, 100));
} else {
killFileStream();
break;
}
}
Alternatively, wrap the loop in a function and call it twice, using the Channels call above to wrap the RandomAccessFile to an InputStream.

Unable to print console output in same format onto text document

I have my java file set up to calculate a phone bill and print out to the console in this format.
Invoice
--------------------------
Account Amount Due
10011 $12.25
10033 $11.70
--------------------------
Total $23.95
but when I run the program I only get this on the text file
Account Amount_Due
10011 $12.25
10033 $11.7
Can someone help me edit my filecreating code in correct format?
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Vector;
public class PhoneBill {
Vector data;
Vector processed = new Vector();
Vector markProcessed = new Vector();
public void readFile(String inFileStr)
{
String str = "";
data = new Vector<LineItem>();
FileReader fReader;
InputStream inFileStream;
try{
fReader = new FileReader(inFileStr);
BufferedReader br=new BufferedReader(fReader);
String line;
while ((line=br.readLine())!= null){
if (line.indexOf("_") != -1)
continue;
else
if (!line.isEmpty()){
data.add(new LineItem(line.trim()));
}
}
br.close();
}
catch (Exception e){
}
}
public void processCharges()
{
String out = "Account Amount_Due\n";
System.out.println ("Invoice");
System.out.println ("--------------------------");
System.out.println ("Account " + "Amount Due ");
double total = 0.0;
double lCharges =0;
boolean done = false;
DecimalFormat numFormatter = new DecimalFormat("$##.##");
for (int j = 0; j < data.size(); j++ ){
LineItem li = (LineItem)data.get(j);
String accNum = li.getAccountNum();
if (j > 0){
done = checkProcessed(accNum);}
else
processed.add(accNum);
if (!done){
lCharges = 0;
for (int i = 0; i < data.size(); i++){
String acc = ((LineItem)data.get(i)).getAccountNum();
if (acc.equals(accNum) && !done)
lCharges += processItemCharges(accNum);
done = checkProcessed(accNum);
}
lCharges+=10.0;
System.out.format ("%s" + " $%.2f%n",accNum, lCharges);
out += accNum+" ";
out += numFormatter.format(lCharges)+"\n";
processed.add(accNum);
total += lCharges;
}
}
System.out.println ("--------------------------");
System.out.format ("%s" + " $%.2f%n","Total", total);
writeToFile("invoice.txt", out);
}
private void writeToFile(String filename,String outStr)
{
try{
File file = new File(filename);
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(outStr);
bw.close();
} catch (IOException ioe){
System.out.println(ioe.getMessage());
}
}
private boolean checkProcessed(String accNum){
if (processed.contains(accNum))
return true;
else
return false;
}
private double processItemCharges(String accNum)
{
double charges = 0.0;
for (int i = 0; i < data.size(); i++)
{
if(((LineItem)data.get(i)).getAccountNum().equals(accNum))
charges += ((LineItem)data.get(i)).getCharges();
}
return charges;
}
public static void main(String[] args)
{
PhoneBill pB = new PhoneBill();
pB.readFile("input_data.txt");
pB.processCharges();
}
class LineItem{
String accNum ;
String timeOfCall;
double mins;
double amountDue;
boolean counted = false;
public LineItem(String accStr)
{
processAccount(accStr);
}
private void processAccount(String accStr){
StringTokenizer st = new StringTokenizer(accStr);
accNum = (String)st.nextElement();
timeOfCall = (String) st.nextElement();
mins = Double.parseDouble((String) st.nextElement());
if (timeOfCall.compareTo("08:00")>0 && timeOfCall.compareTo("22:00")<0)
amountDue = mins*0.10;
else
amountDue = mins*0.05;
}
public String getAccountNum()
{
return accNum;
}
public double getCharges()
{
return amountDue;
}
}
}
Study this. It uses a bit more advanced Java but understanding it will be well worth your while.
package test;
import java.io.*;
import java.util.*;
public class PhoneBill {
private static String BILL_FORMAT = "%-10s $%,6.2f\n";
private static boolean DEBUG=true;
Map<String, List<LineItem>> accounts = new HashMap<String,List<LineItem>>();
public void readFile(String inFileStr) {
FileReader fReader=null;
try {
fReader = new FileReader(inFileStr);
BufferedReader br = new BufferedReader(fReader);
String line;
while ((line = br.readLine()) != null) {
if (line.indexOf("_") != -1)
continue;
else if (!line.isEmpty()) {
LineItem li = new LineItem(line.trim());
List<LineItem> list = accounts.get(li.accNum);
if(list==null){
list = new ArrayList<LineItem>();
accounts.put(li.accNum, list);
}
list.add(li);
}
}
br.close();
} catch (Exception e) {
/* Don't just swallow Exceptions. */
e.printStackTrace();
} finally {
if(fReader!=null){
try{
fReader.close();
} catch(Exception e){
e.printStackTrace();
}
}
}
}
public void processCharges() {
StringBuffer out = new StringBuffer(100)
.append("Invoice\n")
.append("--------------------------\n")
.append("Account Amount Due \n");
double total = 0.0;
double lCharges = 0;
for (String accNum:accounts.keySet()) {
List<LineItem> account = accounts.get(accNum);
lCharges = 10;
for(LineItem li:account){
lCharges += li.getCharges();
}
total += lCharges;
out.append(String.format(BILL_FORMAT, accNum, lCharges));
}
out.append("--------------------------\n");
out.append(String.format(BILL_FORMAT, "Total", total));
writeToFile("invoice.txt", out.toString());
}
private void writeToFile(String filename, String outStr) {
if(DEBUG){
System.out.printf("========%swriteToFile:%s=========\n", '=', filename);
System.out.println(outStr);
System.out.printf("========%swriteToFile:%s=========\n", '/', filename);
}
try {
File file = new File(filename);
// If file doesn't exist, then create it.
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(outStr);
bw.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
}
public static void main(String[] args) {
PhoneBill pB = new PhoneBill();
pB.readFile("input_data.txt");
pB.processCharges();
}
static class LineItem {
String accNum;
double timeOfCall;
double mins;
double amountDue;
boolean counted = false;
private static final double EIGHT_AM = convertTime("08:00");
private static final double TEN_PM = convertTime("22:00");
public LineItem(String accStr) {
processAccount(accStr);
}
private void processAccount(String accStr) {
StringTokenizer st = new StringTokenizer(accStr);
accNum = st.nextToken();
timeOfCall = convertTime(st.nextToken());
mins = Double.parseDouble(st.nextToken());
if (timeOfCall > EIGHT_AM && timeOfCall < TEN_PM)
amountDue = mins * 0.10;
else
amountDue = mins * 0.05;
}
public String getAccountNum() {
return accNum;
}
public double getCharges() {
return amountDue;
}
private static double convertTime(String in){
/* Will blow up if `in` isn't given in h:m. */
String[] h_m = in.split(":");
return Double.parseDouble(h_m[0])*60+Double.parseDouble(h_m[1]);
}
}
}
Printing to the console (i.e. System.out.println) is not the same as concatenating to your out variable (i.e. out+=).
So when you call
writeToFile("invoice.txt", out);
You are only writing what is in the string 'out' to the file. If you look back at your code, you'll see that all of your missing lines are only ever printed to the console, but not concatenated to the 'out' variable. Correct that and you shouldn't have a problem.

Counting distinct words with Threads

The objective is to count distinct words from a file.
UPDATE: Previous Code was successfully finished. Now I have to do the same but using threads (Oh man, I hate them...) and in addition I want to make it with semaphores for better flow.
Code contains some extra stuff left out from previous attempts, I'm trying to figure out what can be used..
I can read one word at a time but mostly I get a "null" in the container. So until I get anything from the container all the time I can't test the Sorter class and so on...
The new addition to the program is WordContainer class to store one word to pass it from reader to sorter:
package main2;
import java.util.ArrayList;
public class WordContainer
{
private ArrayList<String> words;
public synchronized String take()
{
String nextWord = null;
while (words.isEmpty())
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
nextWord = words.remove(0);
notify();
return nextWord;
}
public synchronized void put(String word)
{
while (words.size() > 999)
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
words.add(word);
notify();
}
}
DataSet Class combined with Sorter method resulting in Sorter Class:
package main2;
import java.util.concurrent.Semaphore;
public class Sorter extends Thread
{
private WordContainer wordContainer;
private int top;
private String[] elements;
private boolean stopped;
private Semaphore s;
private Semaphore s2;
public Sorter(WordContainer wordContainer, Semaphore s, Semaphore s2)
{
this.wordContainer = wordContainer;
elements = new String[1];
top = 0;
stopped = false;
this.s = s;
this.s2 = s2;
}
public void run()
{
String nextWord = wordContainer.take();
while (nextWord != null)
{
try
{
s.acquire();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
nextWord = wordContainer.take();
s2.release();
add(nextWord);
}
}
public void startSorting()
{
start();
}
public void stopSorting()
{
stopped = true;
}
public boolean member(String target)
{
if (top > 0)
{
return binarySearch(target, 0, top);
}
else
{
return false;
}
}
private boolean binarySearch(String target, int from, int to)
{
if (from == to - 1)
{
return elements[from].equals(target);
}
int middle = (to - from) / 2 + from;
if (elements[from].equals(target))
{
return true;
}
if (elements[middle].compareTo(target) > 0)
{
// search left
return binarySearch(target, from, middle);
}
else
{
// search right
return binarySearch(target, middle, to);
}
}
public void add(String nextElement)
{
if (top < elements.length)
{
elements[top++] = nextElement;
System.out.println("[" + top + "] " + nextElement);
sort();
}
else
{
String[] newArray = new String[elements.length * 2];
for (int i = 0; i < elements.length; i++)
{
newArray[i] = elements[i];
}
elements = newArray;
add(nextElement);
}
}
private void sort()
{
int index = 0;
while (index < top - 1)
{
if (elements[index].compareTo(elements[index + 1]) < 0)
{
index++;
}
else
{
String temp = elements[index];
elements[index] = elements[index + 1];
elements[index + 1] = temp;
if (index > 0)
{
index--;
}
}
}
}
public int size()
{
return top;
}
public String getSortedWords()
{
String w = "";
for (int i = 0; i < elements.length; i++)
{
w += elements[i] + ", ";
}
return w;
}
public int getNumberOfDistinctWords()
{
return top;
}
}
Reader Class now looks like this:
package main2;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.Semaphore;
public class Reader extends Thread
{
private static final int whitespace = 45;
private static final int word = 48;
private static final int finished = -1;
private WordContainer wordContainer;
private Semaphore s;
private Semaphore s2;
private String[] wordsR;
private int state;
private BufferedReader reader;
private int nextFreeIndex;
public Reader(File words, WordContainer wordContainer, Semaphore s,
Semaphore s2)
{
state = whitespace;
try
{
reader = new BufferedReader(new FileReader(words));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
nextFreeIndex = 0;
wordsR = new String[1];
this.wordContainer = wordContainer;
this.s = s;
this.s2 = s;
}
public void startReading()
{
start();
}
public void run()
{
String nextWord = readNext();
while (nextWord != null)
{
nextWord = readNext();
wordContainer.put(nextWord);
s.release();
try
{
s2.acquire();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public String readNext()
{
int next;
StringBuffer nextWord = new StringBuffer();
while (true)
{
try
{
next = reader.read();
}
catch (IOException e)
{
next = -1;
}
char nextChar = (char) next;
switch (state)
{
case whitespace:
if (isWhiteSpace(nextChar))
{
state = whitespace;
}
else if (next == -1)
{
state = finished;
}
else
{
nextWord.append(nextChar);
state = word;
}
break;
case word:
if (isWhiteSpace(nextChar))
{
state = whitespace;
return nextWord.toString();
}
else if (next == -1)
{
state = finished;
return nextWord.toString();
}
else
{
nextWord.append(nextChar);
state = word;
}
break;
case finished:
return null;
}
}
}
private boolean isWhiteSpace(char nextChar)
{
switch (nextChar)
{
case '-':
case '"':
case ':':
case '\'':
case ')':
case '(':
case '!':
case ']':
case '?':
case '.':
case ',':
case ';':
case '[':
case ' ':
case '\t':
case '\n':
case '\r':
return true;
}
return false;
}
public void close()
{
try
{
reader.close();
}
catch (IOException e)
{
}
}
public String getWords()
{
return wordContainer.take();
}
}
Test Class
package test;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Semaphore;
import main2.Reader;
import main2.Sorter;
import main2.WordContainer;
import junit.framework.Assert;
import junit.framework.TestCase;
public class TestDistinctWordsWithThreads extends TestCase
{
public void test() throws IOException, InterruptedException
{
File words = new File("resources" + File.separator + "AV1611Bible.txt");
if (!words.exists())
{
System.out.println("File [" + words.getAbsolutePath()
+ "] does not exist");
Assert.fail();
}
WordContainer container = new WordContainer();
Semaphore s = new Semaphore(0);
Semaphore s2 = new Semaphore(0);
Reader reader = new Reader(words, container, s, s2);
Sorter sorter = new Sorter(container, s, s2);
reader.startReading();
sorter.startSorting();
reader.join();
sorter.join();
System.out.println(reader.getWords());
Assert.assertTrue(sorter.getNumberOfDistinctWords() == 14720);
/*
* String bible = reader.getWords(); System.out.println(bible); String[]
* bible2 = sorter.getSortedWords(); System.out.println(bible2);
* assertTrue(bible2.length < bible.length());
*/
}
}
Why don't you sinply try something like:
public int countWords(File file) {
Scanner sc = new Scanner(file);
Set<String> allWords = new HashSet<String>();
while(sc.hasNext()) {
allWords.add(sc.next());
}
return allWords.size();
}

Categories