Eclipse console does not show the end result - java

public class PrimeFinder implements Runnable {
Thread go;
StringBuffer primes = new StringBuffer();
int time = 0;
public PrimeFinder() {
start();
while (primes != null) {
System.out.println(time);
try {
Thread.sleep(1000);
} catch(InterruptedException exc) {
// do nothing
}
time++;
}
}
public void start() {
if (go == null) {
go = new Thread(this);
go.start();
}
}
public void run() {
int quantity = 1_000_000;
int numPrimes = 0;
// candidate: the number that might be prime
int candidate = 2;
primes.append("\nFirst ").append(quantity).append(" primes:\n\n");
while (numPrimes < quantity) {
if (isPrime(candidate)) {
primes.append(candidate).append(" ");
numPrimes++;
}
candidate++;
}
System.out.println(primes);
primes = null;
System.out.println("\nTime elapsed: " + time + " seconds");
}
public static boolean isPrime(int checkNumber) {
double root = Math.sqrt(checkNumber);
for (int i = 2; i <= root; i++) {
if (checkNumber % i == 0) {
return false;
}
}
return true;
}
public static void main(String[] arguments) {
new PrimeFinder();
}
}
As the title states I do not get the end result of the program in the console... The timer does count, until the calculation is done, but when the program is supposed to print out the result, the console clears and goes all blank. I tried to enter my code in some kind of online compiler, and sure enough, I got the end result printed out. Has anyone had similar problem and if so, how did you manage to fix it? Thanks in advance!

I tried this in IntelliJ and the output is retained in the console - though it's not all retained when using Eclipse as you point out. Looks like Eclipse maybe overwrites the console upon switching threads.
You could just write the output to a file and view it there, although this is of course different from retaining it in the console. To do that you would go to Run > Run Configurations..., then select your application under Java Application, then click the Common tab, then under Standard Input and Output check the Output file checkbox and enter a log file path and file name for where you want logs to go, then Apply. Then run that "Run Configuration" and view the output in the file.
If running on a server (e.g., tomcat) from within Eclipse, you would go to the Server view, double-click your server, click Open launch configuration, then Common, then Output file. From there you can specify an output destination on your file system or in your Eclipse workspace.

If you started the Thread instead of just doing the instantiation, maybe it would print something out.
Thread thread = new Thread(new PrimeFinder());
thread.start();

Related

Probabilistically Selecting A Set Number of Items Over Time

I have an enterprise application running on a server that accepts files. Tens of thousands of files are submitted every day by users. The customer wants exactly 50 of these files to be automatically selected for audit each day.
The requirements are:
the files must be selected as they come in (we can't wait for all the files to come in and then choose 50 at the end of the day)
the files selected must meet some other criteria, which they haven't told me yet, but I am assured there will still be thousands of files that meet these criteria
the system must not be "game-able". That is - they don't want users who submit files to realise that if they wait until the afternoon or something, their files never get audited. This means we can't just choose the first 50 that come in, the selected files must be randomly spread out throughout the day.
we have to have EXACTLY 50 files. Or so they say. But I'm pretty sure if it just so happened that no user submitted a file that matched the criteria after midday one day, and we only got 25 files, they'd be ok with that. So I can assume that the types of files I'm interested in are submitted with a reasonably regular frequency throughout the day.
I figure then, that I need some function that calculates a probability that a file will be selected, that uses the number of currently chosen files and the time of day as inputs.
I've created a test harness. Please forgive the dodgy code. In this, the "pushTask" thread simulates files coming in by adding them to a stack. "Files" in this test are just Strings with a random number on the end.
The "pullTask" thread simulates files being pulled off the stack. It asks requirementsFunction() if the "file" meets the extra requirements needed (and in this test that's just - does it end in a zero), and it asks probabilityFunction() if it should select the file. If a file is selected, it is printed to System.out.
Really I need some help as to what to put in probabilityFunction(), because at the moment what's in there is garbage (I've left it in so you can see what I've tried). Or if someone knows of a mathematical probability function that uses items/time that would be great too.
package com.playground;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Random;
public class ProbabilisticSelection {
private static int TOTAL_FILES = 1000;
private static int AUDIT_QUANTITY = 10;
private static int TIME_IN_SECONDS_FOR_ALL_FILES = 10;
private Random random = new Random();
private Deque<String> stack = new ArrayDeque<String>();
private boolean finished;
public static void main(String[] args) throws InterruptedException {
new ProbabilisticSelection().test();
}
private void test() throws InterruptedException {
Instant begin = Instant.now();
Runnable pushTask = () -> {
while (!finished) {
int next = random.nextInt(TOTAL_FILES);
String item = "File: " + next;
stack.push(item);
if (Duration.between(begin, Instant.now()).getSeconds() >= TIME_IN_SECONDS_FOR_ALL_FILES) {
finished = true;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable pullTask = () -> {
int itemNumber = 1;
while (itemNumber <= AUDIT_QUANTITY && !finished) {
String poll = stack.poll();
if (requirementsFunction(poll) &&
probabilityFunction(itemNumber, Duration.between(begin, Instant.now()))) {
System.out.println(itemNumber++ + ": "+ poll);
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
finished = true;
Duration delta = Duration.between(begin, Instant.now());
System.out.println();
System.out.println("Retrieved files: " + (itemNumber - 1) + ", should be, " + AUDIT_QUANTITY);
System.out.println("Time taken: " + delta.getSeconds() + ", should be, " + TIME_IN_SECONDS_FOR_ALL_FILES);
};
new Thread(pullTask).start();
new Thread(pushTask).start();
}
private boolean requirementsFunction(String item) {
return item != null && item.endsWith("0");
}
private boolean probabilityFunction(int itemNumber, Duration delta) {
double limit = ((double)(AUDIT_QUANTITY-itemNumber)/(double)AUDIT_QUANTITY + 1); // probability goes down as number of items goes up
double tension = (double)TIME_IN_SECONDS_FOR_ALL_FILES/((double)delta.getSeconds() + 1); // probablity goes up as time nears the end
if (tension == 1) {
return true;
}
double prob = limit * tension * 100;
int rand = random.nextInt(1000);
return prob > rand;
}
}
Algorithm is called Reservoir_sampling, which guarantees fair sampling of k items from some large and unknown N. Hereis Java code

Thread.sleep(time) is not working the way I need it to. I need something better

I'm a student in Denmark trying to make a school project. What I'm working on at this moment is a reader class that takes in a string then prints out word by word and/or letter by letter.
I did some research and found out that Thread.sleep(time) did exactly what I needed it to do. But after I used it I found out it does not work properly! I tried to research some more and found something called a ThreadPoolExecutor but I can figure out how it works in my case.
My reader:
public class TextReader {
// Print method to print word by word from a string
public void wordByWord(String text) throws InterruptedException {
String[] words = text.split(" ");
for (int i = 0; i < words.length; i++) {
System.out.print(words[i] + " ");
Thread.sleep(250);
}
}
// Print method to print letter by letter from a string
public void letterByLetter(String text) throws InterruptedException {
String[] words = text.split(" ");
for (int i = 0; i < words.length; i++) {
String word = words[i] + " ";
char[] letters = (word.toCharArray());
for (int j = 0; j < letters.length; j++) {
System.out.print(letters[j]);
Thread.sleep(250); //so it does not print all the letters at once
}
}
}
}
The reason why Thread.sleep(time) not works in my case is because I need to print to the console and by using Thread.sleep(time) it does not print like a waterfall. It prints either the string I'm trying to break down (time lower than 250ms) or a few letters a once (250 ms) or is just so slow I can't look at it... (over 250ms). I need it to run fast and smooth! So it looks like someone is writing it.
I think I successfully recreated your problem. Every delay lower than about 205 ms seem to cause updating problems. Sometimes the words/letters don't appear but then at the next interval multiple words/letters appear at the same time.
This seems to be a limitation of the Console I/O performance (See this answer). There isn't really anything you can do about this. If you want to output text with a short, minimal delay like this, you need to program your own GUI (for example JavaFX). This will probably solve the performance issues.
Outputs at different delays
205 ms
190 ms
Thread's sleep method takes milliseconds to stop the execution of current thread for specified milliseconds. If it's slow, you can pass less MS and if it's fast then you can increase the timings. So you can tweak according to your need.
ExecutorFramework is a different thing.
It a way to submit your runnable task to the threads managed by ExecutorFramework.
What you are doing is putting a Thread to sleep for that time. That means the thread will become unblocked after that time, however you aren't accounting for the overhead of context switching from another thread. What you want is something more like this
Tried out the ScheduledExecutorService approach and seems to work fine. There's some optimization to be done and some hoops to jump through to wait for the scheduled printing to finish, but it doesn't seem to display the lag (in the two consoles I tried - Eclipse output and Windows Bash).
public class Output {
public static void main(String[] args) {
String toPrint = "Hello, my name is Voldemort, but few call me that.";
StringPrinter printer = new StringPrinter();
printer.print(toPrint, Output::byCharacter, 30);
System.out.println();
printer.print(toPrint, Output::byWord, 150);
}
private static List<String> byWord(String toSplit) {
Iterable<String> it = () -> new Scanner(toSplit);
return StreamSupport.stream(it.spliterator(), false).map(s -> s + " ").collect(Collectors.toList());
}
private static List<String> byCharacter(String toSplit) {
return toSplit.chars().mapToObj(i -> "" + (char) i).collect(Collectors.toList());
}
}
class StringPrinter implements Runnable {
// using an array to be most efficient
private String[] output;
private int currentIndex;
// the service providing the milliseconds delay
private ScheduledExecutorService printExecutor;
public void print(String toOutput, Function<String, List<String>> split, int delay) {
if (printExecutor != null) {
throw new IllegalStateException();
}
printExecutor = Executors.newSingleThreadScheduledExecutor();
List<String> list = split.apply(toOutput);
output = list.toArray(new String[list.size()]);
currentIndex = 0;
printExecutor.scheduleWithFixedDelay(this, 0, delay, TimeUnit.MILLISECONDS);
// wait until output has finished
synchronized (this) {
while (printExecutor != null)
try {
wait(); // wait for printing to be finished
} catch (InterruptedException e) {}
}
}
#Override
public void run() {
if (currentIndex < output.length) {
System.out.print(output[currentIndex++]);
} else {
// mark this print run as finished
printExecutor.shutdown();
printExecutor = null;
synchronized (this) { notifyAll(); }
}
}
}

Carriage return '\r' not reliable when frequently updating the console

I'm displaying progress in the console, and using the '\r' character to clear the line between each update, as per this answer.
public class MainTest {
public static int delay = 10;
public static void main(String[] args) {
for (int i = 0; i <= 100; i++) {
System.out.print("\r");
System.out.print("process:" + i + "%");
Thread.sleep(delay);
}
}
}
With a delay of 240 ms or more, it seems to works fine. However, once I go below this, the '\r' character is not reliable. It looks jittery, and doesn't always clear the line, so at the end you see
process:97%process:98%process:99%process:100%
This gif shows the difference between update speeds. I don't want my program to run slower, just so that the console output looks nice. How can I fix this?
One option is to split your code into two threads, running in parallel. Your worker thread does all your work logic, and updates a 'progress' variable. Every now and then, your UI thread reads the progress, and displays it in the console.
import java.util.concurrent.atomic.AtomicInteger;
public class HelloWorld
{
public static void main(String[] args) throws InterruptedException
{
final AtomicInteger progress = new AtomicInteger(0);
Thread worker = new Thread(new Runnable() {
public void run() {
for (int i = 0; i <= 100; i++) {
try {
// Do some work here
Thread.sleep(1);
progress.set(i);
} catch (InterruptedException e) {
progress.set(100);
}
}
}
});
worker.start();
while (progress.get() < 100) {
// Now you can choose how often to update the console, without
// slowing down your worker.
Thread.sleep(240);
System.out.print("\r");
System.out.print("Progress: " + progress.get() + "%");
}
worker.join();
}
}
It is very common for the UI code to be run on a separate thread to the application logic, mostly so that when something is taking a long time, it doesn't stop the user from interacting - they can still click close, switch between tabs, etc.

Read from stdin but unable to know when to stop

I am running some commnads on commmand prompt. I am waiting for the last command's output to complete. I have to read the output and perform the operation. My command's output is very dynamic and I can not predict when I can stop reading.
I am having issues that I dont know when to stop reading. If suppose I keep the while read(), then my last command output is not ending with new line. Is there any mechenism which can tell me if there has been no activity on stdin for last 5mins, then I get some alert??
The approach I took was to create a class implementing Runnable which monitors the value of a shared AtomicInteger flag. This InputRunnable class sleeps for 5 minutes (300000 ms) and then wakes up to check whether the value has been set by the main method. If the user has entered at least one input in the last 5 minutes, then the flag would be set to 1, and InputRunnable will continue execution. If the user has not entered an input in the last 5 minutes, then the thread will call System.exit() which will terminate the entire application.
public class InputRunnable implements Runnable {
private AtomicInteger count;
public InputRunnable(AtomicInteger count) {
this.count = count;
}
public void run() {
do {
try {
Thread.sleep(300000); // sleep for 5 minutes
} catch (InterruptedException e) {
// log error
}
if (count.decrementAndGet() < 0) { // check if user input occurred
System.exit(0); // if not kill application
}
} while(true);
}
}
public class MainThreadClass {
public static void main(String args[]) {
AtomicInteger count = new AtomicInteger(0);
InputRunnable inputRunnable = new InputRunnable(count);
Thread t = new Thread(inputRunnable);
t.start();
while (true) {
System.out.println("Enter a number:");
Scanner in = new Scanner(System.in);
int num = in.nextInt(); // scan for user input
count.set(1);
}
}
}
I tested this code locally and it appears to be working, but please let me know if you have any issues getting it to run on your system.

New thread freezing application

I have an application which is quite resource intensive, it is using large images as input and some of the operations on these images can take a while. I am therefore looking to make some parts run in their own threads. To do this I have used the following code just to test out first:
Thread t1 = new Thread(new Runnable() {
public void run()
{
inputChooser.setFileFilter(filter);
inputChooser.addChoosableFileFilter(filter);
int img = inputChooser.showOpenDialog(this);
if (img == JFileChooser.APPROVE_OPTION) {
File file = inputChooser.getSelectedFile();
String filename = file.getName();
if (filename.contains("B10")) {
greenBand = 1;
}
if (filename.contains("B20")) {
greenBand = 2;
}
if (filename.contains("B30")) {
greenBand = 3;
}
if (filename.contains("B40")) {
greenBand = 4;
}
if (filename.contains("B50")) {
greenBand = 5;
}
if (filename.contains("B60")) {
greenBand = 6;
}
if (filename.contains("B70")) {
greenBand = 7;
}
try {
greenImage = ImageIO.read(file);
ImageIO.write(greenImage, "JPEG", new File("img2_tmp.jpeg"));
greenImage = ImageIO.read(new File("img2_tmp.jpeg"));
if (greenImage.getWidth() > 8000 | greenImage.getHeight() > 7000) {
greenImage = greenImage.getSubimage(1450, 1400, (greenImage.getWidth()-3200), (greenImage.getHeight()-3000));
}
update(greenImage, greenIcon, greenLabel);
loadingBar.setIndeterminate(false);
checkInput();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Input Image Error", "Input Error", WARNING_MESSAGE);
}
}
}});
t1.start();
When I run the application it freezes when this code is called. However, I have managed to get it to work once, I am not sure how but it ran perfectly (not the first time, it froze a few times first and then randomly worked one time). I haven't changed any of the code just some of the indents and such to get it to fit with the rest of the code and ever since it just continues to freeze. A button action press calls this method where the above code is, as soon as the buttons pressed it freezes.
Is there a reason as to why this is happening?
Thanks in advance
You are calling a non-thread-safe code (swing (is NOT thread safe)) from both threads (newly created and main thread) at the same time.
Make sure that you have decoupled the logic before creating new threads.
For this specific use case, I'd suggest that you use SwingWorkers in stead of threads, they are easy to use, and work well within the limitations of swing.
More about SwingWorkers at http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Hope this helps.
Good luck.
It's difficult to say exactly, but I notice that the variable greenImage and greenBand are not declared anywhere. That makes me think they are global variables. If something else has access to them, it's possible that they're causing some manipulation that sends your code into an infinite loop or does other unexpected Bad Things.

Categories