I have the following thread which simply prints a dot every 200ms:
public class Progress {
private static boolean threadCanRun = true;
private static Thread progressThread = new Thread(new Runnable()
{
public void run() {
while (threadCanRun) {
System.out.print('.');
System.out.flush();
try {
progressThread.sleep(200);
} catch (InterruptedException ex) {}
}
}
});
public static void stop()
{
threadCanRun = false;
progressThread.interrupt();
}
public static void start()
{
if (!progressThread.isAlive())
{
progressThread.start();
} else
{
threadCanRun = true;
}
}
}
I start the thread with this code (for now):
System.out.println("Working.");
Progress.start();
try {
Thread.sleep(10000); //To be replaced with code that does work.
} catch (InterruptedException ex) {}
Progress.stop();
What's really strange is this:
If I use System.out.println('.'); , the code works exactly as expected. (Apart from the fact that I don't want a new line each time).
With System.out.print('.');, the code waits for ten seconds, and then shows the output.
System.out.println:
Print dot, wait 200ms, print dot, wait 200ms etc...
System.out.print:
Wait 5000ms, Print all dots
What is happening, and what can I do to go around this behaviour?
EDIT:
I have also tried this:
private static synchronized void printDot()
{
System.err.print('.');
}
and printDot() instead of System.out.print('.');
It still doesn't work.
EDIT2:
Interesting. This code works as expected:
System.out.print('.');
System.out.flush(); //Makes no difference with or without
System.out.println();
This doesn't:
System.err.print('.');
System.err.flush();
System.out.print('.');
System.out.flush();
Solution: The issue was netbeans related. It worked fine when I run it as a jar file from java -jar.
This is one of the most frustrating errors I have seen in my life. When I try to run this code with breakpoints in debug mode, everything works correctly.
The stdout is line buffered.
Use stderr, or flush the PrintStream after each print.
(This is weird code -- there are much cleaner ways to write and manage threads. But, that's not the issue.)
Your IDE must be buffering by line. Try running it directly on the command line. (And hope that the shell isn't buffering either, but shouldn't.)
The println method automatically flushes the output buffer, the print method not. If you want to see the output immediately, a call to System.out.flush might help.
I think this is because the println() method is synchronized
(This is not an answer; the asker, David, requested that I follow up on a secondary point about rewriting the threading. I am only able to post code this way.)
public class Progress {
private ProgressRunnable progressRunnable = new ProgressRunnable();
public void start() {
new Thread(progressRunnable).start();
}
public void stop() {
progressRunnable.stop();
}
private class ProgressRunnable implements Runnable {
private final AtomicBoolean running = new AtomicBoolean(true);
#Override
public void run() {
while (running.get()) {
System.out.print('.');
System.out.flush();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
private void stop() {
running.set(false);
}
}
public static void main(String[] args) {
Progress progress = new Progress();
progress.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
progress.stop();
}
}
I tested your code, with System.out.print() and System.out.flush(). The code works for me, except for the code:
while (!threadCanRun)
{
Thread.yield();
}
in Progress class. Doing that, the thread is pausing allowing other thread to execute, as you can see in the thread api page. Removing this part, the code works.
But I don't understand why do you need the yield method. If you call Progress.stop(), this will cause to invoke the yield method. After the thread will stop with interrupt, (after waiting a huge amount of time on my pc).
If you want to allow other threads executing and the current thread pausing, consider the join() method.
If you want to stop the current thread, maybe you can consider to remove the
while(!threadCanRun) loop, or place Thread.currentThread().join() before Thread.interrupt() in the stop() method to wait for the completion of other threads, or simply call the p.stop() method .
Take a look to these posts.
Related
I've seen a lot of example for wait and notify, but still I have a problem.
public class Main(){
public static void main(String args[]) throws Exception {
MyThread s = new MyThread();
s.start();
}
}
class MyThread extends Thread {
public void run() {
k();
}
public synchronized void k() {
System.out.println("before wait");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("do something after wait");
}
public synchronized void m() {
for (int i=0;i<6;i++)
System.out.println(i);
notify();
}
}
The only output I get when run the program is: "before wait".
The thread you create in main invokes MyThread#k() which goes into a wait. At that point, that thread will do nothing else until it is awakened or interrupted. But the only place in your code where it could possibly be awakened is the notify in MyThread#m(). Since nothing in your program calls that method, the thread can never be awoken.
What you probably want is to add a call to s.m() right after s.start() in your main program. That way your main thread will execute the notify that's needed to wake up your thread.
Unfortunately, that's very unlikely to work. The problem is that s.start() causes your created thread to become ready to run, but it doesn't necessarily run immediately. It could well happen that your call to s.m() will complete before the created thread does anything. And then you'll still have exactly the same result as before, except that you'll see the integers 0..6 printed out before before wait. The notify will do nothing, because the child thread has not yet performed its wait. (And by the way, since both MyThread#k() and MyThread#m() are both synchronized, increasing your loop limit in MyThread#m() won't change a thing... the child thread won't be able to enter MyThread#k() while MyThread#m() is running. You could improve that by putting the notify in a sycnchronized block rather than making all of MyThread#m() synchronized.)
You can try to get around this by adding Thread.sleep(1000) before s.m() in your main program. That will almost certainly work because your main thread will yield execution, giving your JVM the opportunity to schedule the child thread for some useful work. By the time the main thread wakes out of its sleep and performs its s.m() call, the child will probably have executed its wait and you will then see your do something after wait message.
But that's still pretty crummy, because it still depends on scheduling events that you don't really have any control over. There's still no guarantee that the wait will happen before the notify.
This is why when using wait/notify you should generally arrange for there to be some sort of reliable test as to whether whatever you're waiting to be done has actually occurred. This should be a condition that, once it turns turns true, will remain true at least until the test has been subsequently performed. Then your typical wait loop looks something like this:
while (!isDone()) {
synchronized(monitorObject) {
try {
monitorObject.wait();
} catch (InterruptedException e) {
}
}
}
Putting the whole thing in a loop takes care of premature waking, e.g. due to InterruptedException.
If the required work has already occurred by the time this code is executed, no wait occurs, and the notify executed by the code that did the work was a no-op. Otherwise, this code waits, and the code completing the work will eventually do a notify which will wake this code up as required. Of course, it's critical that, at the time the notify is performed, the wait condition (isDone() above) be true and remain true at least until tested.
Here's a corrected version of your code that incorporates a proper wait loop. If you comment out the Thread.sleep() call, you will likely not see the waiting message, because the work will complete before the wait loop even starts. With the sleep included, you'll probably see the waiting message. But either way, the program will work properly.
public static void main(String[] argv) throws Exception {
MyThread s = new MyThread();
s.start();
Thread.sleep(1000);
s.m();
}
class MyThread extends Thread {
#Override
public void run() {
k();
}
private boolean done = false;
public void k() {
System.out.println("before wait");
while (!done) {
System.out.println("waiting");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
System.out.println("do something after wait");
}
public void m() {
for (int i = 0; i < 6; i++) {
System.out.println(i);
}
synchronized (this) {
done = true;
notify();
}
}
}
The problem is, that you're not calling your m method, so notify is never called, so your thread sleeps forever. You could call it in main, after the start, using s.m():
MyThread s = new MyThread();
s.start();
s.m();
Maybe you should sleep for a little time before calling the m method, as it could run sooner than k in the thread:
s.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// nothing to do
}
s.m();
Not closely related to the question, but a throws declaration in main is not very advisable, even a generated printStackTrace is better than throwing the exception away.
My while(true) is only running once, so I'm trying to add breakpoints to see what's going on, but they never seem to be reached within my run(). I'm using IntelliJ. In the debugger there's a "Threads" tab. Do I need to do something in that tab like select the right thread in order for my breakpoint to be reached? I also see thread names and am wondering how I can find the right thread in this list.
public class MyClass extends ServerWorkflowProcess<OtherClass> {
private ExecutorService executorService = Executors.newSingleThreadExecutor();
...
#Override
public void bootup() {
logger.info("Booting up: " + this);
BackgroundProcess backgroundImpositioner = new BackgroundProcess(this.getCollection());
executorService.submit(backgroundImpositioner);
}
#Override
public void shutdown() {
executorService.shutdown();
}
}
Background process
public class BackgroundProcess implements Runnable {
protected volatile Logger logger = Logger.getLogger(BackgroundImpositioner.class.getName());
Collection<ImpositionWorkstation> impositionWorkstations;
public BackgroundImpositioner(Collection<ImpositionWorkstation> impositionWorkstation) {
this.impositionWorkstations = impositionWorkstation;
}
public void run() {
while(true) {
logger.info("looping");
for (ImpositionWorkstation workstation : impositionWorkstations) {
if (workstation.canAcceptWork()) {
//go do work in another thread so we're not blocking this
workstation.getWorkFromQueue();
try {
workstation.doWork();
} catch (ImpositionException e) {
logger.severe(e.getMessage());
}
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
logger.severe("Background impositioner was interrupted");
}
}
}
}
Side note: the console shows "looping", so I know it gets executed once. The breakpoint never gets hit and it doesn't execute more than once.
It happened to me once that i couldn't make Intellij Idea stop in breakpoints. Basically the problem is that once a thread is stopped in a breakpoint the others won't stop.
There is a setting in the breakpoints properties dialog that prevents this.
Right click on a breakpoint and select 'View Breakpoints'.
On the dialog select a breakpoint.
You will notice on the right of suspend checkbox 2 radio buttons: All and Thread. Select All. Aditionally you can make that the default (Make Default button on the right). The default value will be used for any new breakpoints you add. The old ones need to be changed manually.
EDIT
Additional info on the Intellij help site: Breakpoint options
Don’t let exceptions slip through silently. Use the Future returned by the submit method.
Future<?> f=executorService.submit(backgroundImpositioner);
try {
f.get();
} catch(Exception ex) {
ex.printStackTrace();
}
Then you know more.
The code above is just for finding your actual problem. For production environments you wouldn’t wait for completion but rather log the exception when it occurred, e.g.:
executorService.execute(new FutureTask<Object>(backgroundImpositioner, null)
{
#Override
protected void done() {
if(!isCancelled()) try {
get();
} catch(InterruptedException ex) {
throw new AssertionError("on completed task", ex);
} catch(ExecutionException ex) {
logger.log(Level.SEVERE, "in background task", ex.getCause());
}
}
});
For a reason beyond me, I was not able to breakpoint the while(true) line, but was able to drop breakpoints elsewhere within the run().
If there's no exception thrown inside the run method, i can only assume that one of the calls never returns.
Can you put output statements after every single call to see how far you get?
I guess either workstation.canAcceptWork() or workstation.doWork() is the culprit.
I've met a similar problem that IntelliJ never hits my breakpoint in the run() method of a Runnable class. I found that the only position for the breakpoint to be hit is at the line of public void run() {.
I am starting two thread one after the other.
The first thread is reading in a loop from input and the other one check some condition in a loop to
sent an interrupt to the other.
The problem is that any thread of the two I start first it doesnt let the other stop.
If i start reading in never runs the other thread until it finishes and if I start the other thread is checking the condition in the loop and it wont move forward in code until the condition is true and gets out of the loop.
What is the correct way to do it?
Sample code below:
Thread 1)
public class InterruptionThread extends Thread {
public void run() {
while (condition not true) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (condition true) {
do some work
return;
}
}
}
Thread 2)
public class ReadingThread extends Thread{
public void run() {
int input;
while (true) {
try {
input = stdInput.read();
} catch (IOException e) {
e.printStackTrace();
return;
}
System.out.print((char) input);
}
}
}
This sounds like you are not starting the threads in a correct manner.
Use the start() method to start threads, not the run() method (which doesn't actually start a thread).
new InterruptionThread().start();
new ReadingThread().start();
I think your problem is of producer consumer problem type.
So would suggest you to use BlockingQueue.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
Also instead of directly handling threads; it will be easy if you use Executor Framework; this way thread management will become pretty easy.
In a Java try{} ... catch{} ... finally{} block, code within the finally{} is generally considered "guaranteed" to run regardless of what occurs in the try/catch. However, I know of at least two circumstances under which it will not execute:
If System.exit(0) is called; or,
if an Exception is thrown all the way up to the JVM and the default behavior occurs (i.e., printStackTrace() and exit)
Are there any other program behaviors that will prevent the code in a finally{} block from executing? Under what specific conditions will the code execute or not?
EDIT: As NullUserException pointed out, the second case is actually not true. I thought it was because the text in standard error printed after that in standard out, preventing the text from being seen without scrolling up. :) Apologies.
If you call System.exit() the program exits immediately without finally being called.
A JVM Crash e.g. Segmentation Fault, will also prevent finally being called. i.e. the JVM stops immediately at this point and produces a crash report.
An infinite loop would also prevent a finally being called.
The finally block is always called when a Throwable is thrown. Even if you call Thread.stop() which triggers a ThreadDeath to be thrown in the target thread. This can be caught (it's an Error) and the finally block will be called.
public static void main(String[] args) {
testOutOfMemoryError();
testThreadInterrupted();
testThreadStop();
testStackOverflow();
}
private static void testThreadStop() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
#Override
public void run() {
thread.stop();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testThreadInterrupted() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
#Override
public void run() {
thread.interrupt();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testOutOfMemoryError() {
try {
try {
List<byte[]> bytes = new ArrayList<byte[]>();
while(true)
bytes.add(new byte[8*1024*1024]);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow() {
try {
try {
testStackOverflow0();
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow0() {
testStackOverflow0();
}
prints
finally called after java.lang.OutOfMemoryError: Java heap space
finally called after java.lang.InterruptedException: sleep interrupted
finally called after java.lang.ThreadDeath
finally called after java.lang.StackOverflowError
Note: in each case the thread kept running, even after SO, OOME, Interrupted and Thread.stop()!
Infinite loop in the try block.
Corrupt RAM? Program no longer runs as written? I've actually debugged that once on a DOS machine.
Testing the finally block in different statement in try block.
public static void main(String [] args){
try{
System.out.println("Before Statement");
/*** Statement ***/
System.out.println("After Statement");
}
catch(Exception e){
}
finally{
System.out.println("Finally is Executed");
}
Statements in which finally block is executed are following:
Thread.currentThread().interrupted();
Thread.currentThread().destroy();
Thread.currentThread().stop();
Thread.sleep(10);
Thread.currentThread().interrupt();
Runtime.getRuntime().addShutdownHook(Thread.currentThread());
If there is any exception occurred.
If there is no exception.
Statements in which finally block is not executed are following:
Thread.currentThread().suspend();
System.exit(0);
JVM crashed.
Power to CPU chip goes off.
OS kills JVM process.
Runtime.getRuntime().exit(0);
Runtime.getRuntime().halt(0);
There is a chance of partial execution when finally itself throws an exception (or leads to an error)
One could be "A finally is a part of daeomon thread it may not be executed".
The only times finally won't be called are:
if the power turns off
if you call System.exit()
if the JVM crashes first
if there is an infinite loop in the try block
if the power turns off
I think when JVM exits suddenly due to any reason, that can be a cause the control will not enter into the the finally block and never execute.
You can make it a part of Daemon Thread. You may use the method setDaemon(boolean status) which is used to mark the current thread as daemon thread or user thread and exit the JVM as and when required. This will enable you exit the JVM before finally{} is executed.
Another possible instance of a finally block never executing would be due to a design where the method returned before the try block was entered, as in the cases of some very bad code I've seen from time to time:
public ObjectOfSomeType getMeAnObjectOfSomeType() throws SomeHorrendousException {
if (checkSomeObjectState()) {
return new ObjectOfSomeType();
}
try {
// yada yada yada...
} catch (SomeHorrendousException shexc) {
// wow, do something about this horrendous exception...
} finally {
// do some really important cleanup and state invalidation stuff...
}
I know none of you would ever do this, so I hesitated to add this as a possible scenario, but thought, eh, it's Friday, what the heck ; )
I have a problem with java threads:
public class MyClass{
public void Core(){
runTools(); //here I would like to call runTools() method
}
public void runTools(){
final String run_tool ="cmd.exe /C sources.exe";
Runnable doRun = new Runnable() {
public void run() {
try {
Process tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
}
}
If I do this, then I don't know why, but the thread doesn't work. Please give me some ideas to create a thread. I have already been seen lots of examples, but I should some code such as my example here. Thanks!
At first, if you just want to execute an external command and do not bother about its output*, then using a dedicated thread is unnecessary, since the process itself will already run in parallel to your application, so the exec() call will not really hang your programm.
Nevertheless your code looks correct to me. You should check the working directory of your application (maybe cmd.exe cannot find your sources.exe) and evaluate the output the process you start gives you, by directing the streams of tool_proc.getErrorStream() and tool_proc.getInputStream() to System.out or logging them.
EDIT:
* The Java documentation states you always should read the InputStreams of your processes as failing to do so might result in filling up a system buffer, which will eventually hang the process.
problem 1 You create object for Runnable Interface,that is never possible.
Runnable *obj=new Runnable(); // this is not correct
problem 2 You write definition for Run() method with in the another method runTools()
we can create object for a class that implements The Runnable interface.
Due to these your code is not working.
Try the fallowing way
public class MyClassName1 implements Runnable
{
public void start()
{
//here you can call your method:runTools()
runTool();
}
}
public void runTools()
{
final String run_tool ="cmd.exe /C sources.exe";
try
{
Process tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e)
{
e.printStackTrace();
}
}
here is my main class of the programe
public class MyClassName2
{
public static void main(String[] ars)
{
Runnable *obj1=new MyClassName1();
Thread t=new Thread(obj);
t.start()
}
I hope this helps to you